Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can typedef names be used to declare or define constructors?

Standardese:

[class.ctor] 12.1/1 says

A special declarator syntax is used to declare or define the constructor. The syntax uses:

    — an optional decl-specifier-seq in which each decl-specifier is either a function-specifier or constexpr,

    — the constructor’s class name, and

    — a parameter list

in that order.

[class.name] 9.1/4 says

A typedef-name (7.1.3) that names a class type, or a cv-qualified version thereof, is also a class-name. If a typedef-name that names a cv-qualified class type is used where a class-name is required, the cv-qualifiers are ignored. A typedef-name shall not be used as the identifier in a class-head.

Also [expr.prim.general] 5.1.1/8 says

Where class-name :: class-name is used, and the two class-names refer to the same class, this notation names the constructor (12.1).


Application:

This seems to me to say that declaring a constructor should be allowed using typedef names (despite the fact that 12.1/1 doesn't use an italicized class-name).

For example, given:

struct Foo;
typedef Foo Bar;

then

struct Foo { Bar() {} }; // defines Foo's constructor. - 1

or instead given

struct Foo;
struct Foo { Foo() };
typedef Foo Bar;

then

Foo::Bar() {}; // defines Foo's constructor - 2

or

Bar::Bar() {}; // defines Foo's constructor - 3

or

Bar::Foo() {}; // defines Foo's constructor - 4

Any of these should be legal. However nobody seems to accept definitions 2 or 3, MSVC accepts 1, and MSVC, clang, and gcc all accept 4.

Is my analysis correct, and are all these compilers wrong?

like image 659
bames53 Avatar asked Jul 13 '12 22:07

bames53


1 Answers

§12.1/3 of the working draft N3337 (Feb 2012) states

A typedef-name shall not be used as the class-name in the declarator-id for a constructor declaration.

This rules out (1).

§12.1/1 seems to use the term "declaration" for both declarations and definitions:

A special declarator syntax is used to declare or define the constructor. […] In such a declaration, […]

(without referring to "definitions" explicitly). I think it's a bit unclear whether this applies to out-of-class definitions or only to inline definitions. If it applies to all kinds of definitions, this would rule out (2) and (3) as well. (4) should be legal in any case.

like image 57
Philipp Avatar answered Oct 26 '22 19:10

Philipp