문제

I have code like this:

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?
 };

Do I need the namespace qualifier where Derived refers to it's base class? GCC and MSVC are happy with the code as written, but another compiler complains unless I put the namespace in. What does the C++ standard say?

도움이 되었습니까?

해결책

Inside the class definition B is OK. That's the so-called injected class name.

This also refers to templates (not counting dependent bases). E.g.

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
};

In general the base class (and the class itself) can be referred to inside the class definition without qualification or template arguments.

Quotes from the standard:

9.2 : A class-name is inserted into the scope in which it is declared immediately after the class-name is seen. The class-name is also inserted into the scope of the class itself; this is known as the injected-class-name. For purposes of access checking, the injected-class-name is treated as if it were a public member name.

From this definition it follows that the name of the class itself is publicly accessible from the class, and therefore is available in derived classes. Which proves my point about B being OK along with N::B because the name B is inherited

Btw, this also explains why the following is invalid:

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 Speaks about injected class names in templates. It is far too long to paste here. Hth

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top