在C中,特别是在C 14 n4296中,有两个关于调查员类型的段落,这似乎与我相矛盾 . 见7.2 / 5(在 n4659
中为10.2 / 5):
每个枚举定义一个与所有其他类型不同的类型 . 每个枚举也有一个基础类型 . 可以使用enum-base显式指定基础类型 . 对于作用域枚举类型,如果未明确指定,则基础类型为int . 在这两种情况下,基础类型都被认为是固定的 . 在枚举说明符的右括号之后,每个枚举器都有其枚举类型 . 如果基础类型是固定的,那么闭括号之前的每个枚举器的类型是基础类型,枚举器定义中的constant-expression应该是基础类型的转换常量表达式[...]
5.1.1 / 11( n4659
中的8.1.4.2/4)写道:
表示枚举(7.2)的嵌套名称说明符,后跟该枚举的枚举数名称,是引用枚举数的qualified-id . 结果是枚举器 . 结果的类型是枚举的类型 . 结果是一个prvalue .
然后,当我们在关闭声明的括号之前通过嵌套名称说明符引用枚举器时会发生什么?以下面的代码为例:
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 .
1 回答
我认为这个标准与5.1.1 / 11中的标准相矛盾
和
如果(1)为真,则结果类型应为枚举数的类型,根据7.2 / 5,它是枚举的基础类型或枚举定义的类型,具体取决于它是在枚举之前还是之后闭合支撑 .
这意味着您的代码示例应该编译正常,因为
E::B
是B
,B
的类型是short
.现在,如果你考虑(2),它在结束括号后不会改变任何东西 . 但是如果(2)在结束括号之前为真,则意味着
E::B
的类型是E
,同时B
的类型是short
,所以你最终得到的E::B != B
与(1)相矛盾 .