Pot*_*ter 13 c++ syntax constructor
这是我们在C++第1天学到的东西,我们认为这是理所当然的,但并没有明确遵循标准的措辞.
给定一个类S,我们可以定义它的构造函数
struct S { S(); };
S::S() { … }
Run Code Online (Sandbox Code Playgroud)
但标准似乎也允许这样做:
struct S { S(); };
S() { … }
Run Code Online (Sandbox Code Playgroud)
始终允许使用自身限定类的名称,但始终是多余的.例如S::S::S::S() { … },也是一个有效的声明.如果S::S是,为什么不平淡S?
从C++11§12.1/ 1开始,
构造函数没有名称.特殊的声明符语法用于声明或定义构造函数.语法使用:
- 一个可选的decl-specifier-seq,其中每个decl-specifier都是一个函数说明符或constexpr,
- 构造函数的类名,和
- 参数列表
以该顺序.
这同样适用于类或命名空间范围.有关命名空间范围的特殊规则,§9.3/ 5,
如果成员函数的定义在词法定义之外是词法定义,则成员函数名称应使用::运算符通过其类名限定.
但是,构造函数没有名称,所以这不适用,对吧?而且,没有理由要求资格,因为没有语法歧义.在当前观察到的规则下,声明为没有返回类型和标识符的类名的函数始终是语法错误.对?
并不是说我们应该开始编写省略资格的代码,但是有没有编译器接受这个的原因,或者它只是传统?
当面对S() { }命名空间范围内的标记时,编译器无法神奇地确定它是一个构造函数。哪种语法规则会产生这样的标记序列?让我们忽略除函数定义之外的所有内容;他们无法生产该( ){ }零件。
这意味着S()必须是declarator,并且decl-specifier-seq opt必须为空(请参阅 \xc2\xa78.4.1)。\xc2\xa79.2/7 随后告诉我们声明符必须命名构造函数、析构函数或转换函数。但S也没有点名。因此,S() { }无效。