在C ++中,特别是在C ++ 14 n4296中,有两个关于枚举器类型的争论,这似乎与我矛盾。请参阅7.2 / 5(在中为10.2 / 5 n4659
):
每个枚举定义的类型都不同于所有其他类型。每个枚举都有一个基础类型。可以使用枚举库显式指定基础类型。对于作用域枚举类型,如果未明确指定基础类型,则基础类型为int。在这两种情况下,底层类型都是固定的。在枚举说明符的结尾处,每个枚举器都有其枚举的类型。如果基础类型是固定的,则在右括号之前的每个枚举器的类型都是基础类型,并且枚举器定义中的常量表达式应是基础类型的转换后的常量表达式[...]
5.1.1 / 11(8.1.4.2/4 in n4659
)写道:
表示枚举(7.2)的嵌套名称说明符,后跟该枚举的枚举器的名称,是引用枚举器的限定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。
我认为该标准与您在5.1.1 / 11中所遇到的矛盾
结果是枚举数。(1)
和
结果的类型就是枚举的类型。(2)
如果(1)为true,则结果类型应为枚举数的类型,根据7.2 / 5,它是枚举的基础类型还是枚举定义的类型,具体取决于它是在枚举之前还是之后。右括号。
这意味着您的代码示例应该编译很好,因为E::B
是B
和类型B
IS short
。
现在,如果考虑(2),则在右括号之后它不会改变任何内容。但是,如果(2)在右花括号前为true,则意味着E::B
isE
的类型,同时B
is的类型short
,因此您最终E::B != B
会与(1)相矛盾。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句