在前兩節中(C++模板詳解(一)、C++模板詳解(二)),咱們瞭解了函數模板和類模板的基本概念和使用方法。在這篇博文裏,咱們主要來詳細地闡述一下"模板的參數聲明"這個話題,而且也談及了函數模板和類模板相結合的使用方式和一些注意事項。html
函數模板能夠做爲普通類和模板類的成員函數。下面的這份代碼片斷演示了這一點:函數
template<typename T1> class List { public: // 位於模板類中的成員函數模板定義: template<typename T2> List(const List<T2>& other); // 錯誤的寫法:不能夠是虛函數。 template<typename T1> virtual void func(T1&& t) { } }; // #1: 在類的外部定義上面的構造函數。 template<typename T1> template<typename T2> List<T1>::List(const List<T2>& other) { //... } class Collection { // 位於普通類內部的成員函數模板定義: template<typename T> T* alloc() { //... } // 錯誤的寫法:不能夠是虛函數。 template<typename T> virtual void func(T&& t) { } };
這份代碼展現出了不少的概念。code
不管是普通類仍是模板類,其中的成員函數或是模板成員函數均可之內聯地定義在類中,或是定義在類的外部。在外部定義的成員函數模板能夠具備多個模板參數子句:一個子句做用於該模板自身,其它子句做用於外圍的類模板,其順序是從最外圍的類模板開始,依次到達內部模板。htm
成員函數模板不能夠是虛函數。這是由於,實現虛函數須要使用一個固定大小的虛函數表,每一個虛函數都對應虛函數表的一個入口。然而,成員函數模板的實例化個數,要等到整個程序都編譯完成時才能肯定,這就和"虛函數表的大小是固定的"發生了衝突。因此,成員函數模板不能夠是虛函數。blog
模板類的定義也是能夠嵌套的。例以下面這份示例代碼:get
// 示例1:模板類能夠被嵌套定義在模板類中。 template<typename T1> class List { // 定義並實現。 template<typename T2> class Node1 { }; // 定義。 template<typename T2> class Node2; }; // 外部實現。 template<typename T1> template<typename T2> class List<T1>::Node2 { }; // 示例2:模板類能夠被嵌套定義在普通類中 class Shell { // 定義並實現。 template<typename T> class Inner1 { }; // 定義。 template<typename T> class Inner2; }; // 外部實現。 template<typename T> class Shell::Inner2 { };
相似於成員函數的類外實現,內部類的具體實現也一樣能夠被放到類外進行,它們的書寫規則和模板成員函數幾乎相同。io
函數模板一樣能夠在聲明中提供缺省參數:編譯
template<typename T> void report(const Stack<T>& stack, int number = 10); template<typename T> void fill(const Array<T>& arr, const T& value = T());
因爲和普通函數的缺省參數功能類似,具體的注意事項能夠直接參看:C++函數詳解。模板