Naw*_*waz 43 c++ class definition standards-compliance identifier
这是一个后续问题.
在上一个问题中,@ JohannesSchaub-litb表示以下代码不完全符合标准:
class { int i; }; //unnamed-class definition. § 9/1 allows this!
Run Code Online (Sandbox Code Playgroud)
然后他补充道,
虽然它在语法上是有效的,但它违反了这样一个规则,即这样的类必须在其封闭范围内声明至少一个名称.
我真的不明白这一点.他在说什么名字?
任何人都可以进一步详细说明(最好引用标准)?
Dav*_*men 51
该标准的第9条允许class {public: int i;}(注意缺少最后的分号),因为这个未命名类的decl-specifier-seq可能会用在某些其他构造中,例如typedef或变量声明.问题class {public: int i;};(注意最后的分号现在存在)是这个类规范现在变成了一个声明.根据该标准第7条第3款,这是非法声明:
在这种情况下,除了声明未命名的位字段(9.6)之外,decl-specifier-seq应在程序中引入一个或多个名称,或者重新声明由先前声明引入的名称.
Emi*_*lia 26
问题的关键是,通过声明class{ int i; };你是装配了一堆符号(int i在这种情况下),你将无法在任何其他代码的任何地方使用.
要使此代码有意义,您至少应该执行以下操作之一:
class Myclass { int i; }; //I can furthermore instantiate variables of Myclass
class { int i; } myvar; //This in fact creates a myvar object
typedef class { int i; } MyType; //I can funthermore instantiate variables of MyType
Run Code Online (Sandbox Code Playgroud)
通过说class{ int i; };你只是对编译器说:
int并命名i,class我永远不会打电话给...};)如果从程序中删除该声明,则不会发生任何变化.
CB *_*ley 11
class { int i; };不是有效的声明,因为它是一个没有init-declarator-list的简单声明,但它不引入(或重新声明)类名.
ISO/IEC 14882:2011 7 [dcl.dcl]/3:
在一个简单声明中,只有在声明一个类(第9节)或枚举(7.2)时,也就是说,当decl-specifier-seq包含一个类说明符,一个精心设计的类型时,可以省略可选的init-declarator-list.-specifier with class-key(9.1)或enum-specifier.在这些情况下,只要在decl-specifier-seq中存在类说明符或枚举说明符,这些说明符中的标识符就是声明声明的名称(作为类名,枚举名或枚举数),取决于语法).在这种情况下,除了声明未命名的位字段(9.6)之外,decl-specifier-seq应在程序中引入一个或多个名称,或者重新声明由先前声明引入的名称.
Fre*_*Foo 10
GCC的错误消息非常简洁地解释了它:
$ cat > a.cc
class { int i; };
$ g++ -Wall -std=c++98 a.cc
a.cc:1: error: abstract declarator ‘<anonymous class>’ used as declaration
Run Code Online (Sandbox Code Playgroud)
class { int i; }是一个抽象声明者(标准,§8),但不是一个有效的声明(§7).这是@ JohannesSchaub-litb引用的规则:对于有效的声明,您需要声明一些内容,例如类名或变量名.