У меня проблемы с определением внутреннего класса вне класса, в котором он объявлен.
struct Base {
struct A {
struct B;
};
struct A::B {
};
};
Он компилируется и работает с GCC, но завершается с ошибкой в Clang с этой ошибкой:
innerclass.cpp:6:12: error: non-friend class member 'B' cannot have a qualified name
struct A::B {
~~~^
Если внешний класс Base опущен, код работает на Clang.
Это незаконно, чтобы определить внутренний класс таким образом? Если так, как это должно быть сделано?
Платформа:
OS X 10.8.3
XCode 4.6.2
Clang Apple LLVM версии 4.2 (clang-425.0.24) (на основе LLVM 3.2svn)
GCC GCC версии 4.2.1 (на основе Apple Inc., сборка 5658) (LLVM, сборка 2336.11.00)
Я боюсь, что GCC является разрешающим. В пункте 9/1 стандарта C ++ 11 указано, что -Имя-руководитель класса это:
спецификатор вложенного имени (опция) имя-класса
Это означает, что в качестве имени класса может использоваться квалифицированное имя. Также первая часть пункта 9/11 определяет:
Если -Имя-руководитель класса содержит вложенное имя спецификатор, класса спецификатор будет ссылаться на класс, который был
ранее объявленный непосредственно в классе или пространстве имен, к которому относится вложенное имя спецификатор относится, […]
И ты действительно объявил класс B
внутри класса A
, Тем не менее, вторая часть этого же абзаца добавляет:
[…] и класса спецификатор должен появиться в пространстве имен, включающем предыдущую декларацию. В таких случаях вложенное имя спецификатор из -Имя-руководитель класса определение не должно начинаться с
decltype спецификатор.
В вашем случае класса спецификатор struct A::B { }
делает не появляются в области имен, но в области класса (попробуйте изменить struct Base
в namespace Base
и вы увидите, что Clang принимает это).
Следовательно, правильный способ исправить это — определить класс в области имен, а не внутри Base
:
// ...
struct Base::A::B
{
};
Других решений пока нет …