【问题标题】:Type of an enumerator in the declaration of its enum枚举声明中枚举数的类型
【发布时间】: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


【解决方案1】:

我认为这里的标准与 5.1.1/11 中的标准自相矛盾

结果是枚举数。 (1)

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

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

意味着您的代码示例应该可以正常编译,因为 E::BB 并且 B 的类型是 short

现在,如果您考虑 (2),它在右大括号之后不会改变任何内容。但是如果 (2) 在右大括号之前为真,则意味着E::B 的类型是E,同时B 的类型是short,所以你最终得到E::B != B矛盾(1)。

【讨论】:

    猜你喜欢
    • 2022-01-23
    • 2015-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-22
    • 2023-03-27
    • 2012-09-16
    • 1970-01-01
    相关资源
    最近更新 更多