模板特化和偏特化
(合肥市炮兵學院計算中心 230031)
摘要:本文通過例子介紹了在 c++標準庫中廣泛使用的模板特化和偏特化,並指出了模板特化和偏特化的定義規則和應用規則。
1.引言
c++中的模板分為類模板和函式模板,雖然它引進到c++標準中的時間不是很長,但是卻得到了廣泛的應用,這一點在stl中有著充分的體現。目前,stl在c++社群中得到了廣泛的關注、應用和研究。理解和掌握模板是學習、應用和研究以及擴充stl的基礎。而stl模板例項中又充斥著大量的模板特化和偏特化。
2.模板的定義
(1) 類模板
定義乙個棧的類模板,它可以用來容納不同的資料型別
說明如下:
template
class stack ;
上述定義中,template告訴編譯器這是乙個模板,尖括號中的指明模板的引數,可以有乙個或多個,具體實現時由使用者指定,其中template 中的關鍵字class可以用關鍵字typename來代替。
類模板的使用除了要在宣告時指明模板引數外,其餘均與普通的類相同,例如:
stackint_stack;
stackch_stack;
stackstr_stack;
int_stack.push(10);
ch_stack.push(『z』);
str_stack.push(「c++」);
(2) 函式模板
假設現在要定義乙個max函式來返回同一型別(這種型別是允許比較的)兩個值的最大者.
template
t mymax(const t& t1,const t& t2)
template 的意義與類模板定義中相同。
模板函式的使用與普通非模板函式使用相同,因為模板函式的引數可以從其傳入引數中解析出來。例如:
int highest = mymax(5,10);
char c = mymax(『a』, 』z』);
mymax(5,10)解析出模板函式引數為int, mymax(『a』, 』z』)解析出模板函式的引數為char。
3.模板的特化
(1) 類模板特化
有時為了需要,針對特定的型別,需要對模板進行特化,也就是特殊處理.例如,stack類模板針對bool型別,因為實際上bool型別只需要乙個二進位制位,就可以對其進行儲存,使用乙個字或者乙個位元組都是浪費儲存空間的.
template
class stack {};
template < >
class stack;
上述定義中template < >告訴編譯器這是乙個特化的模板。
(2) 函式模板的特化
看下面的例子
main()
前面兩個mymax都能返回正確的結果.而第三個卻不能,因為,此時mymax直接比較兩個指標p1 和 p2 而不是其指向的內容.
針對這種情況,當mymax函式的引數型別為const char* 時,需要特化。
template
t mymax(const t t1, const t t2)
template <>
const char* mymax(const char* t1,const char* t2)
現在mymax(p1,p2)能夠返回正確的結果了。
4.模板的偏特化
模板的偏特化是指需要根據模板的某些但不是全部的引數進行特化
(1) 類模板的偏特化
例如c++標準庫中的類vector的定義
template
class vector ;
template
class vector;
這個偏特化的例子中,乙個引數被繫結到bool型別,而另乙個引數仍未繫結需要由使用者指定。
(2) 函式模板的偏特化
嚴格的來說,函式模板並不支援偏特化,但由於可以對函式進行過載,所以可以達到類似於類模板偏特化的效果。
template void f(t); (a)
根據過載規則,對(a)進行過載
template < class t> void f(t*); (b)
如果將(a)稱為基模板,那麼(b)稱為對基模板(a)的過載,而非對(a)的偏特化。c++的標準委員會仍在對下乙個版本中是否允許函式模板的偏特化進行討論。
5.模板特化時的匹配規則
(1) 類模板的匹配規則
最優化的優於次特化的,即模板引數最精確匹配的具有最高的優先權
例子:template class vector; // (a) 普通型
template class vector; // (b) 對指標型別特化
template <> class vector ; // (c) 對void*進行特化
每個型別都可以用作普通型(a)的引數,但只有指標型別才能用作(b)的引數,而只有void*才能作為(c)的引數
(2) 函式模板的匹配規則
非模板函式具有最高的優先權。如果不存在匹配的非模板函式的話,那麼最匹配的和最特化的函式具有高優先權
例子: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)
參考文獻
[1] bjarne stroustrup, the c++ programming language (special edition), addison wesley,2000
[2] nicolai m.josuttis, the c++ standard library – a tutorial and reference ,addison wesley,1999
[3] stanley lippman and josée lajoie ,c++ primier, 3rd edition ,addison wesley longman ,1998
特化與偏特化
綜合stl 原始碼剖析中給出的兩種定義,可以如下定義 所謂偏特化的意思是提供另乙份更進一步條件的template定義式,其仍然是模板化的。舉乙個例子 templatestruct test 偏特化版本1 templatestruct test 偏特化版本2 templatestruct test t...
C 模板 特化 與 偏特化
c 模板作為乙個泛化手段,與之相對,對於某種特殊場合,可能要對模板進行相應的特化,偏特化處理。模板為什麼要特化,因為編譯器認為,對於特定的型別,如果你能對某一功能更好的實現,那麼就該聽你的。模板分為類模板與函式模板,特化分為全特化與偏特化。全特化就是限定死模板實現的具體型別,偏特化就是如果這個模板有...
C 全特化與偏特化
c 中用模板來實現 的復用,模板分為類模板與函式模板,雖然模板引進到c 中的時間不長,可是卻在很多方面有很多的應用,比如標準模板庫stl中就有很多應用,然而當我們仔細的學習stl就會發現其中的模板充斥著很多的全特化與偏特化模板,那麼什麼是特化模板呢?我們前面學習了模板知道了編譯的時候編譯器可以根據型...