template
class compare
{
public:
bool IsEqual(T t1, T t2)
{
return t1 == t2;
}
};
int main()
{
char str1[] = "Hello";
char str2[] = "Hello";
compare c1;
compare c2;
cout << c1.IsEqual(1, 1) << endl; //比較兩個int類型的參數
cout << c2.IsEqual(str1, str2) << endl; //比較兩個char *類型的參數
return 0;
}
bool IsEqual(T t1, T t2)
{
return t1 == t2;
}
int main()
{
char str1[] = "Hello";
char str2[] = "Hello";
cout << IsEqual(1, 1) << endl;
cout << IsEqual(str1, str2) << endl;
return 0;
}
上述代碼中,比較字符串是否相等,由於傳入的參數是char *類型的,IsEqual函數模板只是簡單的比較傳入參數的值,即兩個指針是否相等,因此結果為false。顯然,這與我們的初衷不符。因此,上述模板需要對char *類型進行特別處理,即特化。
template <> //告訴編譯器這是一個特化的模板
class compare //特化(char*)
{
public:
bool IsEqual(char* t1, char* t2)
{
return strcmp(t1, t2) == 0; //使用strcmp比較字符串
}
};
注意,如果是在類特化外部定義成員時,成員之前不能加template<>標記。
另外,我們可以只特化成員而不特化類,比如vector中,我們可以只特化push_back操作:
template<>
void vector::push_back(const char *const &val)
{
//...
}
類類型vector
template <>
bool IsEqual(char* t1, char* t2) //函數模板特化
{
return strcmp(t1, t2) == 0;
}
當有多個模板形參時,我們可以只特化一部分形參而不是全部。
c++標准庫中的類vector的定義就是一個例子:
template
class vector { // … // };
template
class vector { //…//};
上述例子中,一個參數被綁定到bool類型,而另一個參數仍未綁定需要由用戶指定。
嚴格來說,函數模板並不支持偏特化,但由於可以對函數進行重載,所以可以達到類似於類模板偏特化的效果。
template void f(T); (a)
根據重載規則,對(a)進行重載
template < class T> void f(T*); (b)
如果將(a)稱為基模板,那麼(b)稱為對基模板(a)的重載,而非對(a)的偏特化。
最優化的優於次特化的,即模板參數最精確匹配的具有最高的優先權
例子:
template class vector{//…//}; // (a) 普通型
template class vector{//…//}; // (b) 對指針類型特化
template <> class vector {//…//}; // (c) 對void*進行特化
每個類型都可以用作普通型(a)的參數,但只有指針類型才能用作(b)的參數,而只有void*才能作為(c)的參數
非模板函數具有最高的優先權。如果不存在匹配的非模板函數的話,那麼最匹配的和最特化的函數具有高優先權
例子:
template void f(T); // (d)
template void f(int, T, double); // (e)
template void f(T*); // (f)
template <> void f (int) ; // (g)
void f(double); // (h)
bool b;
int i;
double d;
f(b); // 以 T = bool 調用 (d)
f(i,42,d) // 以 T = int 調用(e)
f(&i) ; // 以 T = int* 調用(f)
f(d); // 調用(g)