1. 程式人生 > >類和函式模板特例化

類和函式模板特例化

引入原因:編寫單一的模板,它能適應大眾化,使每種型別都具有相同的功能,但對於某種特定型別,如果要實現其特有的功能,單一模板就無法做到,這時就需要模板特例化。
定義:是對單一模板提供的一個特殊例項,它將一個或多個模板引數繫結到特定的型別或值上。

函式模板特例化:必須為原函式模板的每個模板引數都提供實參,且使用關鍵字template後跟一個空尖括號對<>,表明將原模板的所有模板引數提供實參。

template<typename T> //函式模板
int compare(const T &v1,const T &v2)
{
    if(v1 > v2) return
-1; if(v2 > v1) return 1; return 0; } //模板特例化,滿足針對字串特定的比較,要提供所有實參,這裡只有一個T template<> int compare(const char* const &v1,const char* const &v2) { return strcmp(p1,p2); }

特例化版本時,函式引數型別必須與先前宣告的模板中對應的型別匹配,其中T為const char*。

本質:特例化的本質是例項化一個模板,而非過載它。特例化不影響引數匹配。引數匹配都以最佳匹配為原則。例如,此處如果是compare(3,5),則呼叫普通的模板,若為compare(“hi”,”haha”)則呼叫特例化版本(因為這個cosnt char*相對於T,更匹配實參型別),注意,二者函式體的語句不一樣了,實現不同功能。

注意:普通作用於規則使用於特例化,即,模板及其特例化版本應該宣告在同一個標頭檔案中,且所有同名模板的宣告應該放在前面,後面放特例化版本。

類模板特例化:原理類似函式模板,不過在類中,我們可以對模板進行特例化,也可以對類進行部分特例化。對類進行特例化時,仍然用template<>表示是一個特例化版本,例如:

template<>
class hash<sales_data>
{
    size_t operator()(sales_data&);
    //裡面所有T都換成特例化型別版本sales_data
};

按照最佳匹配原則,若T != sales_data,就用普通類模板,否則,就使用含有特定功能的特例化版本。

類模板的部分特例化:不必為所有模板引數提供實參,可以指定一部分而非所有模板引數,一個類模板的部分特例化本身仍是一個模板,使用它時還必須為其特例化版本中未指定的模板引數提供實參。此功能就用於STL原始碼剖析中的traits程式設計。詳見C++primer 628頁的例子。(特例化時類名一定要和原來的模板相同,只是引數型別不同,按最佳匹配原則,那個最匹配,就用相應的模板)

特例化類中的部分成員:可以特例化類中的部分成員函式而不是整個類。

template<typename T>class Foo
{
    void Bar();
    void Barst(T a)();
};
template<>
void Foo<int>::Bar()
{
    //進行int型別的特例化處理
}

Foo<string> fs;
Foo<int> fi;//使用特例化
fs.Bar();//使用的是普通模板,即Foo<string>::Bar()
fi.Bar();//特例化版本,執行Foo<int>::Bar()
//Foo<string>::Bar()和Foo<int>::Bar()功能不同