Глобальная квалификация в объявлении класса class-head

Мы нашли что-то похожее на следующее (не спрашивайте...):

namespace N {
    struct A { struct B; };
}

struct A { struct B; };

using namespace N;

struct ::A::B {}; // <- point of interest

Интересно, что это прекрасно компилируется с VS2005, icc 11.1 и Comeau (онлайн), но не работает с GCC:

глобальная квалификация имени класса недействительна перед токеном '{'

Из С++ 03, Приложение A, мне кажется, что GCC прав:

  • class-head может состоять из nested-name-specifier и identifier
  • nested-name-specifier нельзя начинать с глобальной квалификации (::)
  • очевидно, ни один не может identifier

... или я что-то не понимаю?


person Georg Fritzsche    schedule 06.05.2010    source источник
comment
Звучит как в порядке вещей с VS2005.   -  person wheaties    schedule 06.05.2010


Ответы (1)


Я думаю, вы правильно поняли: в этом случае GCC реализует стандарт буквально, в то время как другие применяют его менее строго (посмотрите на issue #355).

Вы можете сделать следующее, чтобы обойти ограничение синтаксиса

struct identity< ::A >::type::B {}; 

Или вы используете явное имя typedef

typedef ::A AHidden;
struct AHidden::B { };

Или, конечно, вы меняете порядок using namespace и определение вложенного класса. Обратите внимание, что Приложение А носит только информационный характер. Нормативный текст находится в пунктах 5.1/7 и 9.

person Johannes Schaub - litb    schedule 06.05.2010
comment
Спасибо, оперативно и все, что мне нужно :) - person Georg Fritzsche; 06.05.2010