如何用不同的枚举定义不同的模板结构

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 模板参数并对 tx 进行部分特化,因为它们实际上是不同的类型

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

Demo

StrMyEnum 标识模板的名称。
您可以对其进行一般声明,然后进行一些专门化。
但是你不能有第二组声明+专业化(就像你对 XXX 所做的那样)。

您可以做的是用枚举类型和枚举值对一个模板进行参数化。 然后你可以有 2 个级别的专业化:

  1. 针对特定枚举的特定值。
  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

演示:https://godbolt.org/z/zW547T9nf.