中常見的模板類?
模板類英文為class template,template的中文翻譯為模板,所以模板類的意思其實是:類的模板。
顧名思義,模板類是相當于一個模具,當參數給定時,生成具體的類,也叫實例化。它的提出主要是為了減少代碼重復。
例如,我們可以用下面的代碼交換兩個數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;
};
因為,它是一個特化的模板類,所以只有普通模板存在的情況下,它的存在才是合法的,不然我們是對什么進行特化的呢?