Внутри определения класса 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>
{
voiid 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