C++進階--模板及關鍵字typename
阿新 • • 發佈:2018-12-27
//############################################################################ /* * 模板介紹 */ //函式模板 template<typename T> T square(T x) { return x*x; } //類模板 template<typename T> class BoVector { T arr[1000]; int size; public: BoVector():size(0) {} void push(T x) { arr[size] = x; size++; } T get(int i) const { return arr[i]; } int getSize() const { return size; } //void print() const {for(int i=0; i<size; i++) {cout << arr[i] << endl;}} void print() const { const int* p = arr; for(int i=0; i<size; i++) {cout << *(p++) << endl;} } }; template<typename T> BoVector<T> operator*(const BoVector<T>& rhs1, BoVector<T>& rhs2) { BoVector<T> ret; for (int i=0; i<rhs1.getSize(); i++) { ret.push(rhs1.get(i)*rhs2.get(i)); } return ret; } int main() { cout << square(5) << endl; BoVector<int> bv; bv.push(2); bv.push(5); bv.push(8); bv.push(9); bv.print(); cout << "Print squared bv: " << endl; bv = square(bv); bv.print(); } //############################################################################ /* * 函式模板型別省略 */ template<class T> void f() { ... } int main() { f<int>(); // T顯式指定 } // 型別T可以省略 template<class T> void f(T t) { ... } int main() { f(67); // 編譯將其繫結為int型 f<long>(67); // 顯示告訴編譯器為long型別 f(67L); } //############################################################################ /* * 關鍵字typename及其用法 */ template<class T> void printAge(T& item) { ... } template<typename T> void printAge(T& item) { ... } //用於模板引數兩者等效 //使用typename更易理解 // /* * Dependent Type 取決於模板引數的型別 */ template<typename T> A { vector<T> vec; } /* * Nested Dependent Type 包含在某個類裡的dependent type */ template<typename T> A { T::age myAge = 9; vector<T>::iterator itr; } /* * typename 用法二 */ class Dog { public: typedef int age; }; template<class T> void printMyAge(T& item) { int n = 9; T::age* a = &n; cout << (*a) << endl; } int main() { Dog d; printMyAge<Dog>(d); } // 上面的程式碼編譯不過,T::age是型別,編譯器當成變數 //class Wolf { // public: // int age; //}; /* * 法則: 當使用巢狀依賴型別的時候總是在前面加上typename,告訴編譯器這是型別 */ // 例外: 在基類列表或者初始化列表中 template<typename T> class D : public T::NestedBaseClass { public: D(int x) : T::NestedBaseClass(x) { typename T::NestedBaseClass y; ... } } //############################################################################ /* * 模板特化和偏特化 */ // std是一個特殊的名稱空間,我們不能更改它的內容,但是可以為我們的型別提供特化的版本