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