Zohar81
Zohar81

Reputation: 5074

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) ?

Upvotes: 3

Views: 1007

Answers (2)

JeJo
JeJo

Reputation: 32797

Since you ask for , you can make use of if constexpr as follows.

#include <string>

enum struct Enum { EVENT_ONE, EVENT_TWO };

template<Enum e>
constexpr auto get_type_from_enum() noexcept
{
    if constexpr (e == Enum::EVENT_ONE) return int{};
    else if constexpr (e == Enum::EVENT_TWO) return std::string{};
    // ...  more like this ..
}
// type alias for the enum type
template<Enum e> using get_type_from_enum_t = decltype(get_type_from_enum<e>());

template<Enum e> void MyFunc() 
{
    using T = get_type_from_enum_t<e>;
    // ... Do something with T
}

Different from traditional specialization approach. (See Live Demo)

Upvotes: 4

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 122458

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>;
}

Upvotes: 4

Related Questions