Consider this code:
struct foo{}; int main() { foo::foo a; }
I would expect this to be well-formed, declaring a variable of type foo
by the rule in [class]/2 (N4140, emphasis mine):
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. For purposes of access checking, the injected-class-name is treated as if it were a public member name.
clang 3.6.0
agrees with me, compiling the above code with no applicable warnings with -Wall -pedantic
.
gcc 5.2.0
disagrees, providing the following error message:
main.cpp: In function 'int main()': main.cpp:5:5: error: 'foo::foo' names the constructor, not the type foo::foo a;
The above holds no matter how deep the nesting of injected class names, e.g. foo::foo::foo::foo
.
Is there a rule which forces that construct to be interpreted as a constructor in that context, or is this agcc
bug? Or am I interpreting the standards quote incorrectly?
It appears that clang
is wrong in this case. The relevant exception I was looking for is in [class.qual]/2:
2 In a lookup in which function names are not ignored and the nested-name-specifier nominates a class C:
(2.1) if the name specified after the nested-name-specifier, when looked up in C, is the injected-class-name of C, or
[...]
the name is instead considered to name the constructor of class C.
The standard has a near-equivalent (non-normative, obviously) example:
struct A { A(); }; struct B: public A { B(); }; A::A() { } B::B() { } B::A ba;// object of type A A::A a;// error, A::A is not a type name struct A::A a2;// object of type A
However, clang
actually issues a correct diagnostic in this case:
error: qualified reference to 'A' is a constructor name rather than a type wherever a constructor can be declared
Perhaps clang
interprets the line In a lookup in which function names are not ignored
as In a lookup in which a constructor declaration is valid
, but that doesn't seem to be a correct interpretation.
There is an existing bug for this in the clang
bugzilla.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With