模板特化和偏特化
模板特化和偏特化
C++中的模板分為類模板和函數(shù)模板
·模板的特化
(1)類模板特化
有時(shí)為了需要,針對(duì)特定的類型,需要對(duì)模板進(jìn)行特化,也就是特殊處理.例如,stack類模板針對(duì)bool類型,因?yàn)閷?shí)際上bool類型只需要一個(gè)二進(jìn)制位,就可以對(duì)其進(jìn)行存儲(chǔ),使用一個(gè)字或者一個(gè)字節(jié)都是浪費(fèi)存儲(chǔ)空間的.
template <class T>
class stack {};
template<>
class stack<bool>
{
//…//
};
上述定義中template < >告訴編譯器這是一個(gè)特化的模板。并且在聲明特化模板之前一定要有非特化的聲明!并且兩個(gè)類的名字是一樣的!
(2)函數(shù)模板的特化
看下面的例子
int 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);
return 0;
}
前面兩個(gè)mymax都能返回正確的結(jié)果.而第三個(gè)卻不能,因?yàn)?此時(shí)mymax直接比較兩個(gè)指針p1 和 p2 而不是其指向的內(nèi)容.
針對(duì)這種情況,當(dāng)mymax函數(shù)的參數(shù)類型為const char* 時(shí),需要特化。
template <class T>
T mymax(const T t1, const T t2)
{
return t1 < t2 ? t2 : t1;
}
template <>
const char* mymax(const char* t1,const char* t2)
{
return (strcmp(t1,t2) < 0) ? t2 : t1;
}
現(xiàn)在mymax(p1,p2)能夠返回正確的結(jié)果了。
4.模板的偏特化
模板的偏特化是指需要根據(jù)模板的某些但不是全部的參數(shù)進(jìn)行特化
(1) 類模板的偏特化
例如c++標(biāo)準(zhǔn)庫(kù)中的類vector的定義
template <class T, class Allocator>
class vector
{
// … //
};
template <class Allocator>
class vector<bool, Allocator>
{
//…//
};
這個(gè)偏特化的例子中,一個(gè)參數(shù)被綁定到bool類型,而另一個(gè)參數(shù)仍未綁定需要由用戶指定。
(2) 函數(shù)模板的偏特化
嚴(yán)格的來說,函數(shù)模板并不支持偏特化,但由于可以對(duì)函數(shù)進(jìn)行重載,所以可以達(dá)到類似于類模板偏特化的效果。
template <class T> void f(T); (a)
根據(jù)重載規(guī)則,對(duì)(a)進(jìn)行重載
template < class T> void f(T*); (b)
如果將(a)稱為基模板,那么(b)稱為對(duì)基模板(a)的重載,而非對(duì)(a)的偏特化。C++的標(biāo)準(zhǔn)委員會(huì)仍在對(duì)下一個(gè)版本中是否允許函數(shù)模板的偏特化進(jìn)行討論。
5.模板特化時(shí)的匹配規(guī)則
(1) 類模板的匹配規(guī)則
最優(yōu)化的優(yōu)于次特化的,即模板參數(shù)最精確匹配的具有最高的優(yōu)先權(quán)
例子:
template <class T> class vector
{
//…//
}; // (a) 普通型
template <class T> class vector<T*>
{
//…//
}; // (b) 對(duì)指針類型特化
template <>
class vector <void*>
{
//…//
}; // (c) 對(duì)void*進(jìn)行特化
每個(gè)類型都可以用作普通型(a)的參數(shù),但只有指針類型才能用作(b)的參數(shù),而只有void*才能作為(c)的參數(shù)
(2) 函數(shù)模板的匹配規(guī)則
非模板函數(shù)具有最高的優(yōu)先權(quán)。如果不存在匹配的非模板函數(shù)的話,那么最匹配的和最特化的函數(shù)具有高優(yōu)先權(quán)
例子:
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 調(diào)用 (d)
f(i,42,d) // 以 T = int 調(diào)用(e)
f(&i) ; // 以 T = int* 調(diào)用(f)
f(d); // 調(diào)用(h)
C++中的模板分為類模板和函數(shù)模板
·模板的特化
(1)類模板特化
有時(shí)為了需要,針對(duì)特定的類型,需要對(duì)模板進(jìn)行特化,也就是特殊處理.例如,stack類模板針對(duì)bool類型,因?yàn)閷?shí)際上bool類型只需要一個(gè)二進(jìn)制位,就可以對(duì)其進(jìn)行存儲(chǔ),使用一個(gè)字或者一個(gè)字節(jié)都是浪費(fèi)存儲(chǔ)空間的.
template <class T>
class stack {};
template<>
class stack<bool>
{
//…//
};
上述定義中template < >告訴編譯器這是一個(gè)特化的模板。并且在聲明特化模板之前一定要有非特化的聲明!并且兩個(gè)類的名字是一樣的!
(2)函數(shù)模板的特化
看下面的例子
int 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);
return 0;
}
前面兩個(gè)mymax都能返回正確的結(jié)果.而第三個(gè)卻不能,因?yàn)?此時(shí)mymax直接比較兩個(gè)指針p1 和 p2 而不是其指向的內(nèi)容.
針對(duì)這種情況,當(dāng)mymax函數(shù)的參數(shù)類型為const char* 時(shí),需要特化。
template <class T>
T mymax(const T t1, const T t2)
{
return t1 < t2 ? t2 : t1;
}
template <>
const char* mymax(const char* t1,const char* t2)
{
return (strcmp(t1,t2) < 0) ? t2 : t1;
}
現(xiàn)在mymax(p1,p2)能夠返回正確的結(jié)果了。
4.模板的偏特化
模板的偏特化是指需要根據(jù)模板的某些但不是全部的參數(shù)進(jìn)行特化
(1) 類模板的偏特化
例如c++標(biāo)準(zhǔn)庫(kù)中的類vector的定義
template <class T, class Allocator>
class vector
{
// … //
};
template <class Allocator>
class vector<bool, Allocator>
{
//…//
};
這個(gè)偏特化的例子中,一個(gè)參數(shù)被綁定到bool類型,而另一個(gè)參數(shù)仍未綁定需要由用戶指定。
(2) 函數(shù)模板的偏特化
嚴(yán)格的來說,函數(shù)模板并不支持偏特化,但由于可以對(duì)函數(shù)進(jìn)行重載,所以可以達(dá)到類似于類模板偏特化的效果。
template <class T> void f(T); (a)
根據(jù)重載規(guī)則,對(duì)(a)進(jìn)行重載
template < class T> void f(T*); (b)
如果將(a)稱為基模板,那么(b)稱為對(duì)基模板(a)的重載,而非對(duì)(a)的偏特化。C++的標(biāo)準(zhǔn)委員會(huì)仍在對(duì)下一個(gè)版本中是否允許函數(shù)模板的偏特化進(jìn)行討論。
5.模板特化時(shí)的匹配規(guī)則
(1) 類模板的匹配規(guī)則
最優(yōu)化的優(yōu)于次特化的,即模板參數(shù)最精確匹配的具有最高的優(yōu)先權(quán)
例子:
template <class T> class vector
{
//…//
}; // (a) 普通型
template <class T> class vector<T*>
{
//…//
}; // (b) 對(duì)指針類型特化
template <>
class vector <void*>
{
//…//
}; // (c) 對(duì)void*進(jìn)行特化
每個(gè)類型都可以用作普通型(a)的參數(shù),但只有指針類型才能用作(b)的參數(shù),而只有void*才能作為(c)的參數(shù)
(2) 函數(shù)模板的匹配規(guī)則
非模板函數(shù)具有最高的優(yōu)先權(quán)。如果不存在匹配的非模板函數(shù)的話,那么最匹配的和最特化的函數(shù)具有高優(yōu)先權(quán)
例子:
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 調(diào)用 (d)
f(i,42,d) // 以 T = int 調(diào)用(e)
f(&i) ; // 以 T = int* 調(diào)用(f)
f(d); // 調(diào)用(h)
posted on 2013-06-26 11:38 天下 閱讀(868) 評(píng)論(0) 編輯 收藏 引用 所屬分類: C/C++ 、C++模板