如何将枚举模板映射到类型模板?

How to map the Enum template to type template?

我有一个模板函数,目前看起来像这样:

#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>();
}

我想在 enum classtypename template 之间创建一些常量映射,以使其更简单。

理想情况下,此方法应仅获取枚举作为模板,并且类型名模板将使用预定义映射以某种方式解析。

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

在现代 C++(C++17 或 C++20)中是否可行?

你可以编写一个 enum_to_type trait 并相应地专门化它:

#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>();
}

除了作用域枚举之外,这在 C++98 中应该已经没问题了。从 C++11 开始,您可以使用别名模板为其增添趣味:

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

这将允许在使用特征时减少语法混乱:

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

既然你要求 , you can make use of if constexpr 如下。

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

不同于传统的专业化方法。 (See Live Demo)