Search code examples
c++templatesenumsc++17type-traits

How to map the Enum template to type template?


I have got a template function that currently looks like this :

#include <string>

enum class Enum { EVENT_ONE, EVENT_TWO };

template<Enum e, typename T>
void MyFunc() { }

int main(int argc, const char* argv[])
{
    MyFunc<Enum::EVENT_ONE, int>();
    MyFunc<Enum::EVENT_TWO, std::string>();
}

I would like to create some constant mapping between enum class, and the typename template, in order to make it simpler.

Ideally, this method should get only the enum as a template, and the typename template will be somehow resolved using the predefined mapping.

int main(int argc, const char* argv[])
{
    MyFunc<Enum::EVENT_ONE>();
    MyFunc<Enum::EVENT_TWO>();
}

Is it possible in modern C++ (C++17 or C++20) ?


Solution

  • You can write a enum_to_type trait and specialize it accordingly:

    #include <string>
    
    enum class Enum { EVENT_ONE, EVENT_TWO };
    
    
    template <Enum e> struct enum_to_type;
    template <> struct enum_to_type<Enum::EVENT_ONE> { using type = int; };
    template <> struct enum_to_type<Enum::EVENT_TWO> { using type = std::string; };
    // ... maybe more specializations ...
    
    
    template<Enum e>
    void MyFunc() {
        using T = typename enum_to_type<e>::type;
    }
    
    int main(int argc, const char * argv[]) {
        MyFunc<Enum::EVENT_ONE>();
        MyFunc<Enum::EVENT_TWO>();
    }
    

    Apart from the scoped enum this should already be fine in C++98. Since C++11 you can spice it up with an alias template:

    template <Enum e>
    using enum_to_type_t = typename enum_to_type<e>::type;
    

    This would allow less cluttered syntax when using the trait:

    void MyFunc() {
        using T = enum_to_type_t<e>;
    }