1、用const char*實參調用如下模板,則比較的是指標值,而不是指向的字串。此時需要模板特化。
樣本
template <typename T>int compare(const T &v1, const T &v2){if (v1 < v2) return -1;if (v2 < v1) return 1;return 0;}
2、函數模板的特化:一個或多個模板形參的實際類型或實際值是指定的。
• 關鍵字 template 後面接一對空的角括弧(<>);
• 再接模板名和一對角括弧,角括弧中指定這個特化定義的模板形參;
• 函數形參表;
• 函數體。
範例程式碼
// special version of compare to handle C-style character stringstemplate <>int compare<const char*>(const char* const &v1, const char* const &v2){return strcmp(v1, v2);}
特化的聲明必須與對應的模板相匹配。
1)、與任意函數一樣,函數模板特化可以聲明而無須定義。
樣本
// declaration of function template explicit specializationtemplate<>int compare<const char*>(const char* const&, const char* const&);
2)、省略template<>則結果是聲明該函數的重載非模板版本。
樣本
// generic template definitiontemplate <class T>int compare(const T& t1, const T& t2) { /* ... */ }// OK: ordinary function declarationint compare(const char* const&, const char* const&);
當定義非模板函數的時候,對實參應用常規轉換,當特化模板的時候,對實參類型不應用轉換。
3)、如果程式由多個檔案構成,模板特化的聲明必須在使用該特化的每個檔案中出現。
3、類模板的特化
樣本
/* definition of specialization for const char** this class forwards its work to Queue<string>;* the push function translates the const char* parameter to a string* the front functions return a string rather than a const char**/template<> class Queue<const char*> {public:// no copy control: Synthesized versions work for this class// similarly, no need for explicit default constructor eithervoid push(const char*);void pop() {real_queue.pop();}bool empty() const {return real_queue.empty();}// Note: return type does not match template parameter typestd::string front() {return real_queue.front();}const std::string &front() const{return real_queue.front();}private:Queue<std::string> real_queue; // forward calls to real_queue};void Queue<const char*>::push(const char* val){return real_queue.push(val);}
在類特化外部定義成員時,成員之前不能加 template<> 標記。
1)除了特化整個類模板之外,還可以只特化成員,但是成員特化的聲明與任何其他函數模板特化一樣,必須以空的模板形參表開頭。
樣本
template<>void Queue<const char*>::push(const char* const&);
2)類模板的部分特化
類模板的部分特化本身也是模板。編譯器將為執行個體化選擇最特化的模板定義。
樣本
template <class T1, class T2>class some_template {// ...};// partial specialization: fixes T2 as int and allows T1 to varytemplate <class T1>class some_template<T1, int> {// ...};some_template<int, string> foo; // uses templatesome_template<string, int> bar; // uses partial specialization
4、重載與函數模板
函數模板可以重載:可以定義有相同名字但形參數目或類型不同的多個函數模板,也可以定義與函數模板有相同名字的普通非模板函數。
普通函數優先於模板版本。當匹配同樣好時,非模板版本優先。
5、函數模板是建立演算法庫的基礎,類模板是建立標準庫容器和迭代器的基礎。
6、幾個關鍵概念:
1)泛型控制代碼類:儲存和管理指向其他類的指標的類。泛型控制代碼接受單個類型形參,並且分配和管理指向該類型對象的指標。控制代碼類定義了必要的複製控製成員,*,->操作符。不需要瞭解它管理的類型。