在§7.5(C++14)中的示例中,可以找到:
enum {}; // ill-formed
但是,从技术上讲,我认为这个代码是有效的。enum {}
是一个枚举说明符,因此它是一个类型说明符ecl说明符.因此,它是一种简单声明并省略了init声明符列表。这一点已被§7.5所接受。请注意,标识符对于非范围枚举是可选的。此外,clang编译时会发出警告。
编辑
关于提到the *decl-specifier-seq* shall introduce one or more names into the program, or shall redeclare a name introduced by a previous declaration
的答案,我在下面显示了一个编译的typedef声明,但其decl说明符seq在声明中没有引入任何名称:
typedef class {} A;
在C++14 FD中,就在您的示例上方,它解释了声明格式错误的原因:
在简单声明中,可选的init声明符列表可以是仅在声明类(第9条)或枚举(7.2)时省略[…]
在这种情况下,decl说明符seq应引入一个或多个名称添加到程序中,或者应重新声明由之前的声明
因此
enum {} e;
enum {a};
有效-我们的引号不适用于第一个声明,因为它包含一个init声明符,第二个声明引入名称a
作为枚举器。请注意,GCC不会编译第一个声明,这可能是一个错误。
你还提到了的报价
如果枚举器列表为空,则底层类型就像枚举有一个值为
0
的枚举器。
这是关于底层类型的声明,而不是枚举本身,因此与此无关。
typedef class {} A;
为什么要编译
A
是初始化声明符。是的,是-[dcl.dcl]/9:
如果decl说明符seq包含typedef说明符,则声明被称为typedef声明,每个声明的名称init声明符被声明为typedef名称
也就是说,根据这个定义,声明为typedef-names的名称是init声明符。因此,存在一个init声明符列表,并且我们上面的引用不适用。
如果你仔细阅读标准,你会发现很多东西在纯粹的语法层面上是可以接受的,但在文本中是禁止的。这只是这一基本理念的众多实例之一。
其中许多情况都非常明显。让我们考虑一个非常琐碎的问题:一个浮点数。使用类似于标准的语法表示法,我们可以得到以下内容:
"-"opt数字>opt"
那里的一切都是"可选的"。然而,这并不意味着虚无应该被视为一个数字。也不意味着(例如).e
是一个有效的浮点数。这确实意味着,如果其他作品中有一些存在,几乎任何一件作品都可以省略。小数点前和小数点后都不需要数字,所以每个数字本身都是可选的——但其中一个必须存在,所以1.
和.1
都有效,但只有.
无效。同样,.
也是可选的——类似于1e50
的内容是一个完全有效的浮点文字,尽管它在任何地方都不包含.
。
这些限制在与句法符号本身相关的文本中得到了表达。允许(或不允许)的东西必须建立在所有东西的基础上,而不仅仅是孤立的一部分。
标准中明确规定(7项声明)
- 。。。在这种情况下,除未命名位字段(9.6)的声明外,decl说明符seq应引入一个或多个names添加到程序中,或者应该重新声明由之前的声明
此申报
enum {}; // ill-formed
不满足要求。它在程序中既没有引入任何名称。
至于typedef,则
7.1.3 typedef说明符1包含decl说明符的声明typedef声明稍后可以使用的标识符用于命名94)