【发布时间】:2017-02-21 13:56:47
【问题描述】:
在 C++ 中,特别是在 C++14 n4296 中,有两个段落讨论了枚举数的类型,这对我来说似乎是矛盾的。参见 7.2/5(在 n4659 中是 10.2/5):
每个枚举都定义了一个不同于所有其他类型的类型。每个枚举也有一个基础类型。可以使用 enum-base 显式指定基础类型。对于作用域枚举类型,如果未明确指定基础类型,则为 int。在这两种情况下,都说底层类型是固定的。在枚举说明符的右大括号之后,每个枚举数都有其枚举的类型。 如果基础类型是固定的,则右大括号之前的每个枚举器的类型都是基础类型,并且枚举器定义中的常量表达式应该是基础类型的转换常量表达式 [. ..]
而 5.1.1/11(在 n4659 中是 8.1.4.2/4)写道:
表示枚举的嵌套名称说明符 (7.2),后跟该枚举的枚举数的名称,是指代该枚举数的限定 ID。结果是枚举器。 结果的类型是枚举的类型。结果是prvalue。
那么,当我们在声明的右大括号之前通过嵌套名称说明符引用枚举数时会发生什么?以下面的sn-p为例:
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。
【问题讨论】:
-
请注意:5.1.1/11 在 C++17 (n4618) 中是 5.1.4.2/4。
标签: c++ c++14 language-lawyer enumerator