学习处理模板化基类内的名称
如果基类是个模板类,直接调用基类中的方法会不能编译
class A {
public:
void func() { cout << "class A" << endl; }
};
template<class T>
class Base {
public:
void testBase() {
T t;
t.func();
}
};
template<class T>
class Derive : public Base<T> {
public:
void testDerive() {
testBase();
}
};
int main(int argc, char const *argv[])
{
Derive<A> d;
d.testDerive();
return 0;
}
编译不过
$ g++ test-43.cpp -o test-43
test-43.cpp: In member function ‘void Derive<T>::testDerive()’:
test-43.cpp:30:9: error: there are no arguments to ‘testBase’ that depend on a template parameter, so a declaration of ‘testBase’ must be available
由于base class template可能被特化,而特化版本可能不提供和一般性template模板相同的接口。因此编译器往往拒绝在templated base class(模板基类)内寻找继承而来的名称
template<>
class Base<int> {
public:
void testBase2(); // 特化版本没有testBase成员
};
解决方法有三种
解决方法的原理:对编译器承诺,base class template的任何版本(包括特化版本)都将支持一般版本所提供的的接口
- 使用
this
指针调用
template<class T>
class Derive : public Base<T> {
public:
void testDerive() {
this->testBase();
}
};
- 使用
using
template<class T>
class Derive : public Base<T> {
public:
using Base<T>::testBase; // 告诉编译器,testBase在基类中
void testDerive() {
testBase();
}
};
- 显式地指出基类
这种比较不好,无法使用动态绑定
template<class T>
class Derive : public Base<T> {
public:
void testDerive() {
Base<T>::testBase(); // 告诉编译器,testBase在基类中
}
};