Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is a namespace required when referring to the base class

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?

like image 856
user9876 Avatar asked Nov 25 '10 13:11

user9876


1 Answers

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

like image 175
Armen Tsirunyan Avatar answered Oct 11 '22 23:10

Armen Tsirunyan