I've got some (vastly simplified) code along the lines of
inline Type f(const int*) { return Type::Int; }
inline Type f(const double*) { return Type::Double; }
inline void g(int) { }
inline void g(double) { }
However, the type is managed at run-time:
enum class Type { Int, Double } ;
I'd like a utility routine to "convert" from the run-time Type
to a template to avoid a lot of code duplication.
void do_call_f(Type t)
{
if (t == Type::Int)
{
const auto result = f(static_cast<const int*>(nullptr));
}
if (t == Type::Double)
{
const auto result = f(static_cast<const double*>(nullptr));
}
}
void do_call_g(Type t)
{
if (t == Type::Int)
{
g(123);
}
if (t == Type::Double)
{
g(1.23);
}
}
int main()
{
do_call_f(Type::Int);
do_call_f(Type::Double);
do_call_g(Type::Int);
do_call_g(Type::Double);
}
But that's a lot of boiler-plate code in do_call_f()
and do_call_g()
. How can I remove that with a utility routine? No amount of template "magic" seems to work :-(
I'd like something like (pseudo-code)
template<typename TFunc, typename TArg>
auto invoke(Type t, TFunc func, TArg&& arg)
{
if (t == Type::Int)
return func<char>(std::forward<TArg>(arg));
if (type == Type::Double)
return func<double>(std::forward<TArg>(arg));
// ...
}
For my actual code, this should be C++14; but an "I'm curious" answer for C++23 would be acceptable.