Posted by: rmn on: 09/10/2009
In this post I will introduce a common problem you are likely to bump into when inheriting from templated base classes.
The following code has a problem:
template<typename T>
class Base {
T myobj;
public:
void print () { /* ... */ }
};
template<typename T>
class Derived : public Base<T> {
public:
void pretty () {
// ..
print();
}
};
// just to provide a usage example
int main () {
Derived<int> d;
d.pretty();
return 42;
}
The error here is that the compiler is actually unable to find the suitable print() to call from within pretty() function. The print() method is basically what is called a ”non-dependant” name, as it does not (directly) depend on the template parameter. Therefore, while looking up this method the compiler skips the dependant base classes, thus it is unable to find Base<T>::print().
We could have an actual problem if a global print was defined: it would be the one that would be called – producing a much harder and annoying bug to find.
Using the this-pointer would solve the issue completely:
this->print(); // since "this" is actually dependant
Again, a compiler-technology survey:
11/10/2009 at 22:40
You can also say:
using Base::print;
and then the name will be made available.
11/10/2009 at 22:40
This is of course supposed to be Base<T>::print
08/01/2010 at 22:45
@ASk:
Base::printandBase<T>::printwill refer to the same instantiation. More generally, when inside the scope of a derived class, a class template base name may be used without being qualified by its template parameter list.Often times, people will attempt to shorten their code (in a derived class) by using, for example:
typedef Base<T> MyBaseThis is, however, completely redundant.