Reputation: 5074
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
Reputation: 32797
Since you ask for c++17, 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
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