枚举的声明中枚举器的类型

时间:2017-02-21 13:56:48

标签: c++ c++14 language-lawyer enumerator

在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。

1 个答案:

答案 0 :(得分:3)

我认为标准与5.1.1 / 11

中的标准相矛盾
  

结果是枚举器。 (1)

  

结果的类型是枚举的类型。 (2)

如果(1)为真,则结果类型应为枚举数的类型,根据7.2 / 5,它是枚举的基础类型或枚举定义的类型,具体取决于它是否在之前或在闭幕后。

这意味着您的代码示例应该正常编译,因为E::BBB的类型为short

现在,如果考虑(2),它在结束括号后不会改变任何东西。但如果(2)在结束括号之前为真,则表示E::B的类型为E,同时B的类型为short,所以你最终得到的E::B != B与(1)相矛盾。