2.5 型別對型別的映射(Type-to-Type Mapping)
如前所述,不可以對template函數(shù)偏特化。如有下面模板函數(shù):
1 template<class T, class U>
2 T* Create(const U& arg)
3 {
4 return new T(arg);
5 }
用來構(gòu)造一個對象。假設(shè)現(xiàn)在有一個widget對象的構(gòu)造函數(shù)需要兩個參數(shù),第二個固定為-1。那么你沒有辦法如下偏特化,如果你寫一個CreateWidget()來解決,你將不能在泛型程序中使用。
1 //示意代碼,請勿模仿
2 template <class U>
3 widget* Create<widget, U>(const U& arg)
4 {
5 return new widget(arg, -1);
6 }
我們可以通過重載機(jī)制來實現(xiàn),比如傳入一個型別為T的形參:
1 template < class T, class U>
2 T* Create(cosnt U& arg, T /* dummy */)
3 {
4 return new T(arg);
5 }
6 template <class U>
7 widget* Create(const U& arg, widget /* dummy */)
8 {
9 return new widget(arg, -1);
10 }
但是由于形參的傳入,我們構(gòu)造了一個臨時對象,造成額外開銷。我們需要一個輕量級的ID。就是Type2Type:
1 template <typename T>
2 struct Type2Type
3 {
4 typedef T OriginalType;
5 };
6
它沒有任何數(shù)值,但它們各自不同型別。那么,現(xiàn)在可以這樣寫:
1 //依靠重載和Type2Type
2 template <class T, class U>
3 T* Create(const U& arg, Type2Type<T>)
4 {
5 return new T(arg);
6 }
7 template <class U>
8 widget* Create(const U& arg, Type2Type<widget>)
9 {
10 return new widget(arg, -1);
11 }
12 //cleint's code
13 String* pStr = Create("hello", Type2Type<string>());
14 widget* pW = Create(100, Type2Type<widget>());
第二個參數(shù)只是用來選擇適合的重載函數(shù)。