命名空间范围构造函数定义是否需要类限定标识符?

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,

如果成员函数的定义在词法定义之外是词法定义,则成员函数名称应使用::运算符通过其类名限定.

但是,构造函数没有名称,所以这不适用,对吧?而且,没有理由要求资格,因为没有语法歧义.在当前观察到的规则下,声明为没有返回类型和标识符的类名的函数始终是语法错误.对?

并不是说我们应该开始编写省略资格的代码,但是有没有编译器接受这个的原因,或者它只是传统?

MSa*_*ers 2

当面对S() { }命名空间范围内的标记时,编译器无法神奇地确定它是一个构造函数。哪种语法规则会产生这样的标记序列?让我们忽略除函数定义之外的所有内容;他们无法生产该( ){ }零件。

\n\n

这意味着S()必须是declarator,并且decl-specifier-seq opt必须为空(请参阅 \xc2\xa78.4.1)。\xc2\xa79.2/7 随后告诉我们声明符必须命名构造函数、析构函数或转换函数。但S也没有点名。因此,S() { }无效。

\n