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;