wibotwi
wibotwi

Reputation: 118

C++ enums into templated function

I have an enum class and I have this bunch of very similar code that converts enum into templated function call:

auto func1(Type type, ...params)
{
    switch (type)
    {
    case Type::typeA: return func1<Type::typeA>(params);
    case Type::typeB: return func1<Type::typeB>(params);
    case Type::typeC: return func1<Type::typeC>(params);
    ...
    }
}

auto func2(Type type, ...params)
{
    switch (type)
    {
    case Type::typeA: return func2<Type::typeA>(params);
    case Type::typeB: return func2<Type::typeB>(params);
    case Type::typeC: return func2<Type::typeC>(params);
    ...
    }
}

// more such func3, func4, ...

I can generate this code with #define macros. Can I do anything with templates? I can create a template class per each enum type, each class containing all functions. But how to call that function by name?

Upvotes: 0

Views: 104

Answers (2)

Jarod42
Jarod42

Reputation: 217145

You might do something like:

template <typename Func, typename... Params>
auto visit(Func func, Type type, Params&&... params)
{
    switch (type)
    {
    case Type::typeA:
        return func(std::integral_constant<Type, Type::typeA>{}, std::forward<Params>(params)...);
    case Type::typeB:
        return func(std::integral_constant<Type, Type::typeB>{}, std::forward<Params>(params)...);
    case Type::typeC:
        return func(std::integral_constant<Type, Type::typeC>{}, std::forward<Params>(params)...);
    //...
    }
}

With call similar to:

visit([](auto t, int e){ return Func1<t()>(e); }, type, 42);

Demo

Upvotes: 1

super
super

Reputation: 12928

You can pass func1/2/3 as a template template parameter and forward the call to that.

typename <template <typename> typename Func, typename... Params>
auto switchFunction(Type type, Params&&... params) {
    switch (type)
    {
    case Type::typeA: return Func<Type::typeA>(std::forward<Params>(params)...);
    case Type::typeB: return Func<Type::typeB>(std::forward<Params>(params)...);
    case Type::typeC: return Func<Type::typeC>(std::forward<Params>(params)...);
    ...
    }
}

Then you use that like so

auto someOtherFunc(Type type, int param1, double param2)
{
    return switchFunction<func1>(type, param1, param2);
}

For this to work, all versions of func1 has to return the same type.

Additionally all the calls to func1 needs to be valid. Not just the one that is selected by the switch.

Upvotes: 0

Related Questions