如何将枚举模板映射到类型模板?
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 class
和 typename 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>;
}
既然你要求 c++17, 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)
我有一个模板函数,目前看起来像这样:
#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 class
和 typename 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>;
}
既然你要求 c++17, 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)