C++筆記 第五十九課 類模板深度剖析---狄泰學院
阿新 • • 發佈:2018-12-01
如果在閱讀過程中發現有錯誤,望評論指正,希望大家一起學習,一起進步。
學習C++編譯環境:Linux
第五十九課 類模板深度剖析
1.多引數類模板
類模板可以定義任意多個不同的型別引數
類模板可以被特化
指定類模板的特定實現
部分型別引數必須顯示指定
根據型別引數分開實現類模板
類模板的特化型別
部分特化-用特定規則約數型別引數
完全特化-完全顯示指定型別引數
59-1 類模板的特化—重點程式
#include<iostream> #include<string> using namespace std; template <typename T1, typename T2> class Test { public: void add(T1 a, T2 b) { cout << "void add(T1 a, T2 b)" << endl; cout << a + b << endl; } }; template <typename T1, typename T2> class Test <T1*, T2*>//關於指標的特化實現 { public: void add(T1* a, T2* b) { cout << "void add(T1* a, T2* b)" << endl; cout << *a + *b << endl; } }; template <typename T> class Test <T, T>//當Test類模板的兩個型別引數完全相同時,使用這個部分特化實現 { public: void add(T a, T b) { cout << "void add(T a, T b)" << endl; cout << a + b << endl; } void print() { cout << "class Test < T, T>" << endl; } }; template < > class Test <void* , void*>//當 T1== void* 並且 T2== void*時,使用這個完全特化實現 { public: void add(void* a, void* b) { cout << "void add(void* a, void* b)" << endl; cout << "Error to add void* param..." << endl; } }; int main() { Test<int, float> t1; Test<long, long> t2; Test<void*, void*> t3; t1.add(1,2.5); t2.add(5,5); t2.print(); t3.add(NULL, NULL); Test<int*, double*> t4; int a = 1; double b = 0.1; t4.add(&a, &b); return 0; } 執行結果 void add(T1 a, T2 b) 3.5 void add(T a, T b) 10 class Test < T, T> void add(void* a, void* b) Error to add void* param... void add(T1* a, T2* b) 1.1 ******
類模板特化注意事項
特化只是模板的分開實現
本質上是用一類模板
特化類模板的使用方式是統一的
必須顯示指定每一個型別引數
2.問題
類模板特化與重定義有區別嗎?函式模板可以特化嗎?有區別,可以特化。
3.特化的深度分析
重定義和特化的不同
重定義
一個類模板和一個新類(或者兩個類模板)
使用的時候需要考慮如何選擇的問題
特化
以統一的方式使用類模板和特化類
編譯器自動優先選擇特化類
函式模板只支援型別引數完全特化,不支援部分特化
59-2 特化的深入理解
#include<iostream> #include<string> using namespace std; template <typename T1, typename T2> class Test { public: void add(T1 a, T2 b) { cout << "void add(T1 a, T2 b)" << endl; cout << a + b << endl; } }; template <typename T1, typename T2> class Test <T1*, T2*> { public: void add(T1* a, T2* b) { cout << "void add(T1* a, T2* b)" << endl; cout << *a + *b << endl; } }; /* template < > class Test <void* , void*> { public: void add(void* a, void* b) { cout << "void add(void* a, void* b)" << endl; cout << "Error to add void* param..." << endl; } }; */ class Test_Void //重定義 { public: void add(void* a, void* b) { cout << "void add(void* a, void* b)" << endl; cout << "Error to add void* param..." << endl; } }; template //類模板 <typename T> bool Equal(T a, T b) { cout << "bool Equal(T a, T b) " << endl; return a == b; } template//函式模板的完全特化 < > bool Equal<double>(double a, double b) { const double delta = 0.00000000001; double r = a - b ; cout << "bool Equal<double>(double a, double b) " << endl; return (-delta < r) && (r < delta); } bool Equal(double a, double b)//直接進行過載 { const double delta = 0.00000000001; double r = a - b ; cout << "bool Equal(double a, double b) " << endl; return (-delta < r) && (r < delta); } int main() { cout << Equal(1 , 1) << endl; //cout << Equal<double>(0.001, 0.001) << endl;和cout << Equal<>(0.001, 0.001) << endl;兩種寫法是等價的 //cout << Equal(0.001, 0.001) << endl;//呼叫全域性過載函式,因為編譯器優先選擇 cout << Equal<>(0.001, 0.001) << endl;//告訴編譯器放棄過載函式,直接使用模板完全特化 return 0; } 執行結果 bool Equal(T a, T b) 1 bool Equal<double>(double a, double b)//函式模板的完全特化實現 1
4.工程中的建議
當需要過載函式模板時,優先考慮使用模板特化;當模板特化無法滿足需求,再使用函式過載!
小結
類模板可以定義任意多個不同的型別引數
類模板可以被部分特化和完全特化
特化的本質是模板的分開實現
函式模板只支援完全特化
工程中使用模板特化代替類(函式)重定義