macos — двухуровневый вложенный класс c ++ работает с GCC, но не работает с Clang

У меня проблемы с определением внутреннего класса вне класса, в котором он объявлен.

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)

3

Решение

Я боюсь, что GCC является разрешающим. В пункте 9/1 стандарта C ++ 11 указано, что -Имя-руководитель класса это:

спецификатор вложенного имени (опция) имя-класса

Это означает, что в качестве имени класса может использоваться квалифицированное имя. Также первая часть пункта 9/11 определяет:

Если -Имя-руководитель класса содержит вложенное имя спецификатор, класса спецификатор будет ссылаться на класс, который был
ранее объявленный непосредственно в классе или пространстве имен, к которому относится вложенное имя спецификатор относится
, […]

И ты действительно объявил класс B внутри класса A, Тем не менее, вторая часть этого же абзаца добавляет:

[…] и класса спецификатор должен появиться в пространстве имен, включающем предыдущую декларацию. В таких случаях вложенное имя спецификатор из -Имя-руководитель класса определение не должно начинаться с
decltype спецификатор.

В вашем случае класса спецификатор struct A::B { } делает не появляются в области имен, но в области класса (попробуйте изменить struct Base в namespace Base и вы увидите, что Clang принимает это).

Следовательно, правильный способ исправить это — определить класс в области имен, а не внутри Base:

// ...

struct Base::A::B
{
};
5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]