模板派生類(下面的D) 從一個 確定性基類(指B)繼承,
在D的定義中, 編譯器優先查找基類中的名字, 然后才是模板參數placeholder (即Type) .
例如:
struct B
{
typedef int Type; //基類中有一個Type名字
};
template<class Type>
class D : public B //從非依賴基類B派生,
{
public:
Type i; //Type既可以是模板參數, 有可能是基類B中被typedef的int, 優先選擇后者
};
int main()
{
D<char> d;
d.i = 29; //d.i 的確切類型應該是 B中定義的 int, 而不是模板實參指定的char.
return 0;
}
VC7.1 確實如此.
這樣, 是否造成一種現象,就是如果一個模板類需要繼承一個普通的基類,它在確定模板參數名字的時候還要考慮
到基類中去看看有沒有同名沖突?
或者使用一種防御性的模板參數命名方法,即僅僅將模板參數命名為T, U這樣的簡單類型?
C++ Templates <The complete guide> 中的一個例子:
一個模板基類
template<class T>
class Base
{
public:
int field; // #1
};
派生類, 從上面的模板基類繼承
注意, 在此, 基類并不能確定就是上面的Base<T>,
因為 下面#3 處可以看到, 程序對Base<int>進行了特化
template<class T>
class Derived : public Base<T>
{
public:
void f()
{
field++; //#2 哪個field? #1處還是#3處,
}
};
#2處的field到底是char還是int類型? 即#1處還是#3處 ? 顯然無法確定, 只有當
Derived被某個特定的T類型實例化的時候才知道.
template<>
class Base<int>
{
public:
char field; //#3
};
#2處的field是一個unqualified name, 而基類Base<T>是一個dependent name, 因此不去其中查找.
正確的編譯器做法是: 在#1處報錯. VC7.1就是如此.
因此在Derived<T>模板類中, 如果確實需要指定Base<T>中的field, 應該使用 this->field 或者 Base<T>::field.