顧名思義,模板類是相當於壹個模具,當參數給定時,生成具體的類,也叫實例化。它的提出主要是為了減少代碼重復。
例如,我們可以用下面的代碼交換兩個數b和c
a = b;
b = c;
c = a;
這個交換過程與a,b,c的具體類型沒有關系,因此我們可以用它來交換兩個整數,或者兩個浮點數。更壹般的,我們可以用來交換兩個具有賦值運算符的類型。因此,可以用模板進行壹般化:
template<class T>
void swap(T &b, T &c){
a = b;
b = c;
c = a;
}
當然,上面介紹的這個不是模板類,而是模板函數。不過他們的概念是類似的。其中壹開始的template代表後面尖括號中的是模板參數(類似於函數的參數),class代表參數是類(相應的,可以用template<int N>來聲明整型參數)。後面的代碼和的函數基本沒有區別,只是用T來代替了具體的類型,例如int,double等。根據需要我們可以用swap<int>(b,c)來交換兩個整數,swap<double>(b,c)交換兩個浮點數。由於編譯器可以根據b,c的具體類型推導T的具體含義,因此可以簡寫為swap(b,c)。
回到模板類,假設我們需要壹個類型來代表動態數組,且該類型支持size成員函數。如果是整型的類,我們可能會寫
class vector_int{
size_t size() const;
};
如果某壹天,我們又需要浮點類型的動態數組,可能又會寫
class vector_double{
size_t size() const;
};
於是就會發現它們的代碼是如此的類似,因此我們希望將它壹般化。如同swap函數的做法,我們將它定義為模板類:
template<class T>
class vector{
size_t size() const;
};
因此,vec_int等同於vector<int>,而vector_double等同於vector<double>。因為運用模板類的語法類似於
vector<T> a;
因此,編譯器沒辦法為我們推導T的具體含義,所以不能像模板函數壹樣進行簡寫。
當然,上面是比較簡單的情況,有時候我們需要的類在大多數情況下是壹樣的,但是對於某幾個特殊情形可能不太壹樣,例如我們可能希望對於bool類型的數組能盡量減少內存的使用,用壹個比特位代表壹個bool值。從而,我們的數組不是通過bool a[10]的形式來定義。在這種情況下,c++提供了模板特化,也就是說當模板的參數取某個具體的值時,我們使用不同的模板,定義方式如下:
template<>
class vector<bool>{
size_t size() const;
};
因為,它是壹個特化的模板類,所以只有普通模板存在的情況下,它的存在才是合法的,不然我們是對什麽進行特化的呢?