试图理解 C++14 中的 §7.2/6

Trying to understand §7.2/6 in C++14

7.2/6 (C++14):

An enumeration whose underlying type is fixed is an incomplete type from its point of declaration (3.3.2) to immediately after its enum-base (if any), at which point it becomes a complete type. An enumeration whose underlying type is not fixed is an incomplete type from its point of declaration to immediately after the closing } of its enum-specifier, at which point it becomes a complete type.

看看下面的代码片段(参见 live example):

enum A{} t;                 // enum A{} is a complete type (OK)
enum class B:int z;         // enum class B:int is not a complete type
int main()
{
}

明白为什么B不是完整类型了。但是,仅通过查看上面的段落,这对我来说似乎不太清楚。 z 在枚举的 enum-base 之后声明,其底层类型是固定的,同样的方式 t 在结束 [=14] 之后声明=] 的 枚举说明符 的基础类型不固定的枚举器。

问题不在于 B 不完整。如您自己的引用所示,它在 enum-base: int 之后立即完成。问题是您正在使用语法不允许的结构。

type-specifier 产生式允许关键字 enum 以两种方式出现在其中 ([dcl.type]):

  1. 详细类型说明符中
  2. 枚举说明符中。

包含 enum 详细类型说明符 看起来像 ([dcl.type.elab])

enum nested-name-specifieropt identifier

这不适合您的代码,而且不能声明新类型(参见 [basic.lookup.elab]/p2)。也就是说,虽然 struct A* pa; 即使没有事先声明 A 也是合法的,但 enum B * pb; 是不合法的。

一个 enum-specifier ([dcl.enum]/p1) 是

之一

enum-head { enumerator-listopt }
enum-head { enumerator-list , }

无需深入研究 enum-head 是什么,很明显这需要大括号,这不在您的代码中。

enum class B : int; 是一个 opaque-enum-declaration,其语法是

enum-key attribute-specifier-seqopt identifier enum-baseopt ;

这不允许您声明枚举本身以外的任何内容。

简而言之,语法根本不允许enum class B:int z;。相反,您可以编写 enum class B:int; B z;,这是完全有效的,尽管 : int 是多余的。