Reputation: 868
struct A{};
int A;
struct A a;
struct A::A b;
The last two declarations above are equivalent.They both declare objects of type A. Where in the Standard can I find or deduce this?
Upvotes: 8
Views: 249
Reputation: 60989
[class]/2:
A class-name is inserted into the scope in which it is declared immediately after the class-name is seen. The class-name is also inserted into the scope of the class itself; this is known as the injected-class-name.
I.e. A::A::A::A
refers to A
as well. In some contexts, A::A
could name the constructor instead, though - [class.qual]/2 covers this, and its note even addresses your example:
In a lookup in which function names are not ignored33 and the nested-name-specifier nominates a class
C
- if the name specified after the nested-name-specifier, when looked up in
C
, is the injected-class-name ofC
(Clause 9), or- in a using-declaration (7.3.3) that is a member-declaration, if the name specified after the nested-name- specifier is the same as the identifier or the simple-template-id’s template-name in the last component of the nested-name-specifier,
the name is instead considered to name the constructor of class
C
. [ Note: For example, the constructor is not an acceptable lookup result in an elaborated-type-specifier so the constructor would not be used in place of the injected-class-name. — end note ]
33) Lookups in which function names are ignored include names appearing in a nested-name-specifier, an elaborated-type- specifier, or a base-specifier.
So in a statement such as
A::A a;
Function names are not ignored when looking up A::A
, and thus the code is ill-formed as A::A
refers to the constructor. However, in
struct B : A::A {};
struct A::A a;
Everything is fine as function names are ignored in base-specifiers and elaborated-type-specifiers.
Upvotes: 9