在C ++中,特别是在C ++ 14 n4296中,有两个段落讨论了枚举器的类型,这似乎与我相矛盾。见7.2 / 5(n4659
中的10.2 / 5):
每个枚举定义一个与所有其他类型不同的类型。每个枚举也有一个基础类型。可以使用enum-base显式指定基础类型。对于作用域枚举类型,如果未明确指定,则基础类型为int。在这两种情况下,基础类型都被认为是固定的。在enum-specifier的右括号之后,每个枚举器都有其枚举类型。 如果基础类型是固定的,则右括号前的每个枚举器的类型是基础类型,枚举器定义中的常量表达式应是基础类型的转换常量表达式[。 ..]
5.1.1 / 11(n4659
中的8.1.4.2/4)写道:
表示枚举(7.2)的嵌套名称说明符,后跟该枚举的枚举数名称,是引用枚举数的qualified-id。结果是枚举器。 结果的类型是枚举的类型。结果是prvalue。
然后,当我们在关闭声明的括号之前通过nested-name-specifier引用枚举器时会发生什么?以下面的代码段为例:
template < typename T1, typename T2 >
struct fail_if_not_same {
static_assert(std::is_same<T1, T2>::value, "Fail!");
static constexpr int value = 0;
};
enum class E : short {
A,
B = A + 1,
C = fail_if_not_same<decltype(B), short>::value,
D = fail_if_not_same<decltype(E::B), short>::value
};
上面的表达式E::B
是什么类型的?这是标准的矛盾吗? gcc和clang都遵循7.2 / 5。
答案 0 :(得分:3)
我认为标准与5.1.1 / 11
中的标准相矛盾结果是枚举器。 (1)
和
结果的类型是枚举的类型。 (2)
如果(1)为真,则结果类型应为枚举数的类型,根据7.2 / 5,它是枚举的基础类型或枚举定义的类型,具体取决于它是否在之前或在闭幕后。
这意味着您的代码示例应该正常编译,因为E::B
为B
且B
的类型为short
。
现在,如果考虑(2),它在结束括号后不会改变任何东西。但如果(2)在结束括号之前为真,则表示E::B
的类型为E
,同时B
的类型为short
,所以你最终得到的E::B != B
与(1)相矛盾。