模板初步——定義模板
阿新 • • 發佈:2017-11-18
main strong 函數類 unsigned ati 顯式 make 類模板 友元
一、關鍵點
定義函數模板&類模板
模板參數列表:非類型參數
類模板類名的使用:依據作用域是否加上模板類型
類模板和友元:設置友好關系
模板參數:使用類的類型成員、默認模板實參
成員模板的使用:非模板類的成員模板、模板類的成員模板
二、定義函數模板
//模板參數T是一個類型 template <typename T> bool cmp(const T &a, const T &b) { return a < b; } //模板參數N是一個非類型參數 template <unsigned N> void get_val(int (&arr)[N]) { for (const auto &v : arr) cout << v << " "; }
註:一個非類型參數可以一個整型,或者是一個指向對象或函數類型的指針或(左值)引用。
註:綁定到非類型整型參數的實參必須是一個常量表達式(從而允許編譯器在編譯時實例化模板)。
三、定義類模板
template <typename T> class Blob { public: using size_type = typename vector<T>::size_type; //... } int main() { Blob<int> b; return 0; }
四、類模板的成員函數
template <typename T> class Blob { public: using size_type = typename vector<T>::size_type; //... private: void check(size_type i, const string &s) const; }; //成員函數類外定義 template <typename T> void Blob<T>::check(size_type i, const string &msg) const { //... }
註:定義在類模板內的成員函數被隱式聲明為內聯函數。
註:一個類模板的成員函數只有在使用時才被實例化。
五、類模板的友元
友元是模板:類可以授權給所有友元模板實例,也可以只授權給特定實例
友元不是模板:友元被授權可以訪問所有模板實例
1. 一對一友好關系(友元是模板,且友元的模板類型與類模板的一致)
//Blob的友元是模板函數operator==和模板類BlobPtr template <typename> class Blob; //該聲明是operator==函數的參數聲明所需要的 template <typename T> bool operator==(const Blob<T>&, const Blob<T>&); template <typename> class BlobPtr; //該聲明是Blob中的友元聲明所需要的 template <typename T> class Blob { //每個Blob實例將訪問權限授予用相同類型實例化的BlobPtr和相等運算符 friend class BlobPtr<T>; friend bool operator==(const Blob<T>&, const Blob<T>&); //... };
template <typename T> class pal;
template <typename T> class C { //C的每個實例將相同實例化的pal聲明為友元 friend class pal<T>; }
template <typename T> class pal; class C { //用類C實例化的pal是C的一個友元 friend class pal<C>; }
2. 通用和特定的模板友好關系
template <typename T> class C { //pal的所有實例都是C的每個實例的友元 template <typename X> friend class pal; }
class C { //pal的所有實例都是C的友元 template <typename X> friend class pal; }
template <typename T> class C { //pal是C所有實例的友元 friend class pal; //非模板類 }
註:可以將模板類型參數聲明為友元
六、模板參數
1. 使用類的類型成員
T::value_type * p;
上面這句代碼的默認含義是T類型的名為value_type的static數據成員與名為p的變量相乘。
為了顯式聲明value_type是一個模板類型參數的類型成員,我們可以如下定義:
typename T::value_type * p;
2. 默認模板實參
與函數默認實參一樣,對於一個模板參數,只有當它右側的所有參數都有默認實參時,它才可以有默認實參。
如果一個類模板為其所有模板參數都提供了默認實參,且我們希望使用這些默認實參,那就要:
template <class T = int> class C { //... }; C<> c1; //空<>表示我們希望使用默認實參 C<double> c2;
七、成員模板
成員模板:本身是模板的成員函數,它不能是虛函數
1. 模板類的成員模板
template <typename T> class Blob { template <typename It> //此構造函數有自己的模板類型參數It Blob(It b, It e); //... } template <typename T> template <typename It> Blob<T>::Blob(It b, It e) :data(make_shared<vector<T>>(b, e)) { }
2. 非模板類的成員模板
與正常的函數模板沒有區別,只不過作用域是在類內
模板初步——定義模板