如何用不同的枚举定义不同的模板结构
How to define the different template structs with different enums
我有两个枚举如下:
enum TTT {t = 2};
enum XXX {x = 2};
我正在尝试创建一些结构来帮助我获取枚举的名称。这是我所做的:
template<TTT>
struct StrMyEnum {
static char const* name() { return "unknown"; }
};
template<>
struct StrMyEnum<t> {
static char const* name() { return "tt"; }
};
有效。现在我可以获得枚举的名称 t
: StrMyEnum<t>::name()
.
但是,如果我为 XXX
编写另一组模板结构,它似乎不起作用。
template<XXX>
struct StrMyEnum {
static char const* name() { return "unknown"; }
};
template<>
struct StrMyEnum<x> {
static char const* name() { return "xx"; }
};
现在我得到一个编译错误:could not convert 'x' from 'XXX' to 'TTT'
。似乎编译器正在尝试将 StrMyEnum<x>
与 TTT
...
匹配
我不知道为什么。
所以模板无法区分不同的枚举?是否可以为不同的枚举编写一些结构?
您可以使用 C++17 Non-type 模板参数并对 t
和 x
进行部分特化,因为它们实际上是不同的类型
enum TTT { t = 2 };
enum XXX { x = 2 };
template<auto>
struct StrMyEnum {
static char const* name() { return "unknown"; }
};
template<>
struct StrMyEnum<t> {
static char const* name() { return "tt"; }
};
template<>
struct StrMyEnum<x> {
static char const* name() { return "xx"; }
};
StrMyEnum
标识模板的名称。
您可以对其进行一般声明,然后进行一些专门化。
但是你不能有第二组声明+专业化(就像你对 XXX
所做的那样)。
您可以做的是用枚举类型和枚举值对一个模板进行参数化。
然后你可以有 2 个级别的专业化:
- 针对特定枚举的特定值。
- 特定枚举的默认值。
查看下面的代码:
#include <iostream>
enum TTT { t = 2, t2 = 3 };
enum XXX { x = 2, x2 = 3 };
template <typename T, T val>
struct StrMyEnum {
static char const* name() { return "unknown"; }
};
// Default specialization for TTT:
template <TTT t>
struct StrMyEnum<TTT, t> {
static char const* name() { return "TTT"; }
};
// Specialization for TTT::t:
template <>
struct StrMyEnum<TTT, t> {
static char const* name() { return "TTT::t"; }
};
// Specialization for XXX::x:
template <>
struct StrMyEnum<XXX, x> {
static char const* name() { return "XXX::x"; }
};
int main()
{
std::cout << StrMyEnum<TTT, t2>().name() << std::endl;
std::cout << StrMyEnum<TTT, t>().name() << std::endl;
std::cout << StrMyEnum<XXX, x2>().name() << std::endl;
std::cout << StrMyEnum<XXX, x>().name() << std::endl;
return 0;
}
输出:
TTT
TTT::t
unknown
XXX::x
我有两个枚举如下:
enum TTT {t = 2};
enum XXX {x = 2};
我正在尝试创建一些结构来帮助我获取枚举的名称。这是我所做的:
template<TTT>
struct StrMyEnum {
static char const* name() { return "unknown"; }
};
template<>
struct StrMyEnum<t> {
static char const* name() { return "tt"; }
};
有效。现在我可以获得枚举的名称 t
: StrMyEnum<t>::name()
.
但是,如果我为 XXX
编写另一组模板结构,它似乎不起作用。
template<XXX>
struct StrMyEnum {
static char const* name() { return "unknown"; }
};
template<>
struct StrMyEnum<x> {
static char const* name() { return "xx"; }
};
现在我得到一个编译错误:could not convert 'x' from 'XXX' to 'TTT'
。似乎编译器正在尝试将 StrMyEnum<x>
与 TTT
...
我不知道为什么。
所以模板无法区分不同的枚举?是否可以为不同的枚举编写一些结构?
您可以使用 C++17 Non-type 模板参数并对 t
和 x
进行部分特化,因为它们实际上是不同的类型
enum TTT { t = 2 };
enum XXX { x = 2 };
template<auto>
struct StrMyEnum {
static char const* name() { return "unknown"; }
};
template<>
struct StrMyEnum<t> {
static char const* name() { return "tt"; }
};
template<>
struct StrMyEnum<x> {
static char const* name() { return "xx"; }
};
StrMyEnum
标识模板的名称。
您可以对其进行一般声明,然后进行一些专门化。
但是你不能有第二组声明+专业化(就像你对 XXX
所做的那样)。
您可以做的是用枚举类型和枚举值对一个模板进行参数化。 然后你可以有 2 个级别的专业化:
- 针对特定枚举的特定值。
- 特定枚举的默认值。
查看下面的代码:
#include <iostream>
enum TTT { t = 2, t2 = 3 };
enum XXX { x = 2, x2 = 3 };
template <typename T, T val>
struct StrMyEnum {
static char const* name() { return "unknown"; }
};
// Default specialization for TTT:
template <TTT t>
struct StrMyEnum<TTT, t> {
static char const* name() { return "TTT"; }
};
// Specialization for TTT::t:
template <>
struct StrMyEnum<TTT, t> {
static char const* name() { return "TTT::t"; }
};
// Specialization for XXX::x:
template <>
struct StrMyEnum<XXX, x> {
static char const* name() { return "XXX::x"; }
};
int main()
{
std::cout << StrMyEnum<TTT, t2>().name() << std::endl;
std::cout << StrMyEnum<TTT, t>().name() << std::endl;
std::cout << StrMyEnum<XXX, x2>().name() << std::endl;
std::cout << StrMyEnum<XXX, x>().name() << std::endl;
return 0;
}
输出:
TTT
TTT::t
unknown
XXX::x