user1609012
user1609012

Reputation: 301

Compiler Error When Calling Base Constructor when both Base and Derived are Templated With Derived Type Parameter

I am struggling to understand why the following code does not compile:

template <class T>
class Base {
    public:
        Base(int a){}
};
template <class T>
class Derived: public Base<T>  {
    public:
        Derived(int a): Base(a){}
};
int main(){}

On my compiler (gcc 5.4.0 with C++ 11) this outputs the error message

error: class 'Derived<T>' does not have any field named 'Base'
         Derived(int a): Base(a){}

I see that this is somewhat similar to Template base constructor call in member initialization list error, though that test case actually compiles for me while this one does not: The main difference seems to be that both Base and Derived use the same type parameter. Additionally, it compiles fine if I explicitly add the type parameters or I give an explicit scope for base, as in

template <class T>
class Base {
    public:
        Base(int a){}
};

template <class T>
class Derived: public Base<T>  {
    public:
        Derived(int a): Derived::Base(a){}
};

int main(){}

What's going on? Am I misunderstanding when injected class names may be used?

Upvotes: 5

Views: 427

Answers (1)

Brian Bi
Brian Bi

Reputation: 119174

The injected class name Base is a member of the class Base, and since the base class is dependent, its scope is not searched during unqualified name lookup. As such, using the name Base will only find the class template, not the injected class name of Base<T>. That is why you must write Base<T>.

Derived::Base works because it causes name lookup to be postponed until Derived is instantiated.

Upvotes: 6

Related Questions