c++模板特化

一、模板特化, specialization of template
模板特化(specialization of template)並不是說實例化一個模板,如template <class T>,class stack<T>;聲明stack<int>,這是實例化一個模板類。類模板特化的意思是,對於某個特定的類型,需要對模板進行特殊化,即特殊的處理。例如,stack類模板針對bool類型有特化,因爲實際上bool類型只需要一個二進制位,就可以對其進行存儲,使用一個字或者一個字節都是浪費存儲空間的.同樣,函數模板特化也是針對某個特定類型的特殊處理,一個比較經典的例子:
template <class T>
T mymax(const T t1, const T t2)
{
    return t1 < t2 ? t2 : t1;
}
main()
{
   int highest = mymax(5,10);//正確結果
   char c = mymax(‘a’, ’z’);//正確結果
   const char* p1 = “hello”;
   const char* p2 = “world”;
   const char* p = mymax(p1,p2);//錯誤結果,因爲比較的是指針,而不是內容
}
 
如果需要得到正確結果就需要針對const char*的函數模板特化:
const char* mymax(const char* t1,const char* t2)
{
    return (strcmp(t1,t2) < 0) ? t2 : t1;
}
 
// 類的基模板
template <class T,class T1>
class MyClass
{
};

// 類偏特化
template <class T1>
class MyClass<bool,T1>
{
};

// 類全特化
template <>
class MyClass<bool,int>
{
};

二、模板偏特化,partial specialization of template
模板的偏特化是指需要根據模板的某些但不是全部的參數進行特化。
1. 類模板的偏特化
例如c++標準庫中的類vector的定義
template <class T, class Allocator>
class vector { // … // };
template <class Allocator>
class vector<bool, Allocator> { //…//};
這個偏特化的例子中,一個參數被綁定到bool類型,而另一個參數仍未綁定需要由用戶指定。
 
2. 函數模板偏特化
嚴格的來說,函數模板並不支持偏特化,但由於可以對函數進行重載,所以可以達到類似於類模板偏特化的效果。
   template <class T> void f(T);   (a)
   根據重載規則,對(a)進行重載
   template <class T> void f(T*);   (b)
   如果將(a)稱爲基模板,那麼(b)稱爲對基模板(a)的重載,而非對(a)的偏特化。C++的標準委員會仍在對下一個版本中是否允許函數模板的偏特化進行討論。

三、模板特化時的匹配規則
(1) 類模板的匹配規則
最優化的優於次特化的,即模板參數最精確匹配的具有最高的優先權
例子:
template <class T> class vector{//…//}; // (a)   普通型
template <class T> class vector<T*>{//…//};   // (b) 對指針類型特化
template <>    class vector <void*>{//…//};   // (c) 對void*進行特化
每個類型都可以用作普通型(a)的參數,但只有指針類型才能用作(b)的參數,而只有void*才能作爲(c)的參數
(2) 函數模板的匹配規則
非模板函數具有最高的優先權。如果不存在匹配的非模板函數的話,那麼最匹配的和最特化的函數具有高優先權
例子:
template <class T> void f(T);   // (d)
template <class T> void f(int, T, double); // (e)
template <class T> void f(T*);   // (f)
template <> void f<int> (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);   //   調用(h)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章