C++ Logo

std-discussion

Advanced search

Disambiguation about constructor declaration seems underspecified (to say the least)

From: Tam S. B. <cpplearner_at_[hidden]>
Date: Mon, 7 Dec 2020 12:18:11 +0000
Consider ``` typedef int a1, a2, a3; typedef char a4; namespace ns { class A { typedef A(a1); // #1 friend A(a2)(); // #2 static A(a3); // #3 explicit A(a4); // #4 }; } ``` Clang rejects #1, complaining that "typedef name must be an identifier", while MSVC, GCC, ICC accept it. GCC and ICC seem to treat #1 as a valid declaration with redundant parentheses (i.e. equivalent to `typedef A a1;`). MSVC seems to ignore `typedef` and treat #1 as a valid declaration of constructor whose parameter type is `a1` (i.e. equivalent to `A(a1);`). Clang, MSVC, and GCC reject #2 (complaining that "function cannot return function type"), while ICC seems to consider it equivalent to `friend A a2();`. All compilers reject #3, complaining that "constructor cannot be declared 'static'". Everyone agrees that #4 is a valid constructor declaration. I can't find anything in the standard that specifies this behavior. I only found [dcl.spec.general]/3 <http://eel.is/c++draft/dcl.spec.general#3.sentence-1>: > If a _type-name_ is encountered while parsing a _decl-specifier-seq_, it is interpreted as part of the _decl-specifier-seq_ if and only if there is no previous _defining-type-specifier_ other than a _cv-qualifier_ in the _decl-specifier-seq_. This seems to suggest that in all these declarations, `A` should be considered to be the type of the entity being declared, instead of the constructor name, which does not match reality. I believe that the standard should clarify how these declarations should be interpreted. In particular, it needs to specify when the name of the current class (the "injected-class-name") is considered to name a constructor in declarations like these.

Received on 2020-12-07 06:18:15