Reputation: 301
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
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