C++ 是否允许使用具有相同整数值的枚举专门化模板?

C++ 是否允许使用具有相同整数值的枚举专门化模板?,c++,language-lawyer,c++17,C++,Language Lawyer,C++17,看看这个简单的片段: enum class Enum1 { Value }; enum class Enum2 { Value }; template <auto> struct Foo; template <> struct Foo<Enum1::Value> { }; template <> struct Foo<Enum2::Value> { }; enum类Enum1{Value}; 枚举类Enum2{Value}; 模板结构

看看这个简单的片段:

enum class Enum1 { Value };
enum class Enum2 { Value };
template <auto> struct Foo;
template <> struct Foo<Enum1::Value> { };
template <> struct Foo<Enum2::Value> { };
enum类Enum1{Value};
枚举类Enum2{Value};
模板结构Foo;
模板结构Foo{};
模板结构Foo{};
Clang对此进行编译,但gcc-7.2失败:

x、 cpp:5:20:错误:重新定义“struct Foo”模板 结构Foo{}

此错误消息似乎无效,在第5行,写入了
Enum2::Value

哪个编译器是正确的?这是一致性代码吗?

在:

包含占位符类型的类型
T
和相应的初始值设定项
e
,确定如下:

  • 对于使用包含占位符类型的类型声明的非类型模板参数,
    T
    是非类型模板参数的声明类型,
    e
    是相应的模板参数
这似乎表明推断的类型将是
decltype(Enum1::Value)
,而值将是
Enum1::Value


decltype(Enum1::Value)
是否等于
decltype(Enum2::Value)
?此代码

static_assert(std::is_same_v<decltype(Enum1::Value), decltype(Enum2::Value)>);
静态断言(std::is_same_v);
…无法同时使用clang++6g++8进行编译


我认为您可能已经暴露了gcc中的一个bug。正如评论中指出的,还有一个问题

有一个错误报告打开:


还请注意,两个编译器都接受以下代码:

template <typename T, T> struct Foo;
template <> struct Foo<decltype(Enum1::Value), Enum1::Value> { };
template <> struct Foo<decltype(Enum2::Value), Enum2::Value> { };
模板结构Foo;
模板结构Foo{};
模板结构Foo{};

template
与之不同的行为(IMHO)令人惊讶且不受欢迎。

本段似乎表明,在比较显式专门化的模板ID时,GCC不包括非类型模板参数的类型是正确的:(顺便说一句,只需尝试
Foo
vs
Foo
@johanneschaub-litb,就可以更容易地揭示差异-您指的是“它们相应的整型或枚举型非类型模板参数具有相同的值和”?它肯定适用于
template struct Foo
,因为这两个值的类型相同。但我认为在这种情况下,它不是很明确,也没有尝试过。是否有任何类型的衰减应该像
0
vs
0L
情况下那样发生?对于它的价值,在一个更简单的情况下,标准还说。“模板参数类型的转换常量表达式”。这表明应该考虑该类型。我认为Clang和GCC在这里都不是错的。这可能需要一份缺陷报告。它应该非常清楚。我怀疑措辞缺陷,因为这与非类型参数不同。