Подтвердить что ты не робот

Требуется ли пространство имен при обращении к базовому классу

У меня такой код:

namespace N {
   class B {
     public:
       virtual void doStuff(B *) = 0;
    };
 }

 // not in a namespace
 class Derived : public N::B {
   public:
       void doStuff(B *); // Should this be N::B, or is B ok?
 };

Нужен ли мне определитель пространства имен, где Derived ссылается на его базовый класс? GCC и MSVC довольны кодом, написанным, но другой компилятор жалуется, если я не помещаю пространство имён. Что говорит стандарт С++?

4b9b3361

Ответ 1

Внутри определения класса B все в порядке. Это так называемое введенное имя класса.

Это также относится к шаблонам (не считая зависимых баз). Э.Г.

template <class T> class B{};
template <class T> class C: public B<int>
{
   void f(B* p) {} //same as B<int>* p
   void f(C* p) {} //same as C<T>* p
};

Как правило, на базовый класс (и на сам класс) можно ссылаться внутри определения класса без уточнения или аргументов шаблона.

Цитаты из стандарта:

9.2: имя класса вставляется в область, в которой оно объявляется сразу после того, как имя класса замечено. Имя класса также вставляется в область действия самого класса; это известно как впрыскивается класс имя. В целях проверки доступа имя_инъектированного класса обрабатывается так, как если бы оно было открытым именем участника.

Из этого определения следует, что имя самого класса является общедоступным из класса и, следовательно, доступно в производных классах. Что доказывает мою точку зрения о том, что B в порядке вместе с N :: B, потому что имя B наследуется

Кстати, это также объясняет, почему следующее недействительно:

template <class T> class B{};
template <class T> class C: public B<T>
{
     void f(B* p){} //ERROR
    // the above is invalid!! Base class is dependent therefore 
    //its scope is not considered during unqualified name lookup
     void g(typename C::B* p){} //this is valid, same as B<T>* p  
};

14.6.1. Говорит о введенных именах классов в шаблонах. Это слишком долго, чтобы вставить здесь. Hth