程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 重學C++ (十二) 模板特化和偏特化

重學C++ (十二) 模板特化和偏特化

編輯:C++入門知識

重學C++ (十二) 模板特化和偏特化


一、模板的定義

1.類模板

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;
}

2.函數模板

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 *類型進行特別處理,即特化。

1.類模板特化

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

2.函數模板特化

template <> 
bool IsEqual(char* t1, char* t2) //函數模板特化
{
    return strcmp(t1, t2) == 0;
}

三、模板偏特化

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)的偏特化。

四、模板特化時的匹配

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. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved