C++实验课遇到的这个问题,子类调用父类(这两个类都是模板类)成员时报错为未定义,这里补上学习笔记
#include<iostream>
template <typename T>
class Parent{
protected:
T x;
public:
Parent(T a):x(a){}
};
template <typename T>
class Child : public Parent<T>{
private:
T y;
public:
Child(T a, T b):Parent<T>(a){
this-> y = b;
}
void showAll(void){
std::cout<< "x:" << x << std::endl;
std::cout<< "y:" << y << std::endl;
}
};
int main()
{
Child<int> c(1,2);
c.showAll();
return 0;
}
报错:
test2.cpp: In member function ‘void Child<T>::showAll()’:
test2.cpp:21:33: error: ‘x’ was not declared in this scope
std::cout<< "x:" << x << std::endl;
原因:
C++的模板中的名称会进行两次查找,称为两阶段查找(two-phase lookup)。对于一个非依赖型名称(不以任何方式依赖于模板参数的名称),在模板声明进行解析的时候就会进行查找。但C++标准中规定(14.6.2 3),一个非受限的名称查找的时候将不会考虑依赖型的基类。所以
因为有偏特化,所以一个模板子类其实是不能在实例化之前就知道他的模板父类到底是谁,因此名字也无法resolve,所以只能this->了。不过VC++有个小扩展,允许你不使用this->就可以调用父类的名字,特别方便。由此可见,其实也是完全可以做到的。
查找不到就会错误。解决办法是把它变成一个依赖型名称:
在x前加
1.this->或者Parent::
2.子类中添加using Parent::x;