rasmusb
rasmusb

Reputation: 438

Two level nested c++ class works with GCC but fails with Clang

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

Answers (1)

Andy Prowl
Andy Prowl

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

Related Questions