试图理解 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]):
- 在 详细类型说明符中。
- 在枚举说明符中。
包含 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
是多余的。
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]):
- 在 详细类型说明符中。
- 在枚举说明符中。
包含 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
是多余的。