Reputation: 438
I'm having problems defining an inner class outside of the class in which it is declared.
struct Base {
struct A {
struct B;
};
struct A::B {
};
};
It compiles and works with GCC but fails on Clang with this error:
innerclass.cpp:6:12: error: non-friend class member 'B' cannot have a qualified name
struct A::B {
~~~^
If the outermost class Base is omitted the code works on Clang.
Is it illegal to define an inner class this way? If so, how should it be done?
Platform:
OS X 10.8.3
XCode 4.6.2
Clang Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
GCC gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
Upvotes: 3
Views: 1262
Reputation: 126502
I'm afraid GCC is being to permissive. Paragraph 9/1 of the C++11 Standard specifies that a class-head-name is a:
nested-name-specifier(opt) class-name
Which means a qualified name can be used as the name of a class. Also, the first part of paragraph 9/11 specifies:
If a class-head-name contains a nested-name-specifier, the class-specifier shall refer to a class that was previously declared directly in the class or namespace to which the nested-name-specifier refers, [...]
And you did indeed declare class B
inside class A
. However, the second part of the same paragraph adds:
[...] and the class-specifier shall appear in a namespace enclosing the previous declaration. In such cases, the nested-name-specifier of the class-head-name of the definition shall not begin with a decltype-specifier.
In your case, the class-specifier struct A::B { }
does not appear in the scope of namespace, but in the scope of a class (try changing struct Base
into namespace Base
and you will see that Clang accepts it).
Therefore, the correct way of fixing this is to define the class at namespace scope, and not inside Base
:
// ...
struct Base::A::B
{
};
Upvotes: 5