C++ template 学习归纳2
關于c++中的類模板,常見的形式為:
template<typename T> class className{//... };比如筆者在這里舉一個例子:
?
#include <iostream> #include<vector> #include <stdexcept>template<typename T> class stack{ private:std::vector<T> elems; public:void push(T const&);void pop();T top() const;bool empty() const{return elems.empty();} };template<typename T> void stack<T>::push(T const& a){elems.push_back(a); }template<typename T> void stack<T>::pop(){if(elems.empty()){throw std::out_of_range("stack<T>::pop empty");}return elems.pop_back(); }template<typename T> T stack<T>::top()const{if(elems.empty()){throw std::out_of_range("stack<T>::top empty");}return elems.back(); }int main(){return 0; }從上面的代碼可以看出,為了定義成員函數,我們使用了下面的形式,比如:
template<typename T> void stack<T>::push(T const& a){elems.push_back(a); }本來在此處有一個問題的,也就是關于類成員函數的實現位置的問題,這個問題我們稍后會提到。
現在我們為了測試上面的例子可以使用下面的函數代碼:
int main(){stack<int> intStack;intStack.push(1);intStack.push(2);std::cout<<intStack.top()<<std::endl;stack<std::string> strStack;strStack.push("hello");std::cout<<strStack.top()<<std::endl;return 0; }我們有些時候會遇到這樣的代碼,比如:
stack<stack<int> > intStack;在這種情況下,我們要注意就是兩個“>”中間的那個空格,那個是必須的,否則的話,編譯器會認為是“>>”。這一點大家寫代碼的時候要注意。
下面我們來看看類模板的特化:
當我們想特化一個類模板的時候,我們就需要用template<>開頭,后面更上我們希望特化的代碼。比如:
template<> class myStack<std::string>{//... };對于特化類模板而言,就如同編寫普通的類成員函數一樣,比如:
void myStack<int>::pop(int const& a){//... }下面我們呢來看看類模板的局部特化。
例如對于下面的代碼:
template<typename T1,typename T2> class myClass{/... };而言,以下幾種像是的局部特化都是正確 的:
//局部特化 兩個參數一致 template<typename T> class myClass<T,T>{//... };//局部特化 第二個為int template<typename T> class myClass<T,int>{//... };//兩個參數都為指針類型 template<typename T1,typename T2> class myClass<T1*,T2*>{//... };在下面的例子中:
myClass<int float>mif; //將使用<T1,T2> myClass<float,float>mif; //將使用<T> myClass<float,int>mif; //將使用<T,int> myClass<int*,double*>mp; //將使用<T1*,T2*>大家要注意下面的錯誤代碼,
myClass<int,int>m; myClass<int*,int*>m;z這兩個代碼在上面的這個例子中都是錯誤的。前者因為會和myClass<T,T>產生二義性。后者會和myClass<T,T>產生二義性、使得編譯器不知道應該匹配哪一個。
如果想解決上面的第二個二義性的話,我們可以專門特化下面的代碼:
template<typename T> class myClass<T*,T*>{//... };接下來我們來看看預設模板參數:
我們先來看看代碼再說,大家注意和上面的例子進行比較:
#include <iostream> #include<vector> #include <deque> #include <cstdlib> #include <stdexcept>template<typename T,typename CONT=std::vector<T> > class stack{ private:CONT elems; public:void push(T const&);void pop();T top() const;bool empty() const{return elems.empty();} };template<typename T,typename CONT> void stack<T,CONT>::push(T const& a){elems.push_back(a); }template<typename T,typename CONT> void stack<T,CONT>::pop(){if(elems.empty()){throw std::out_of_range("stack<T>::pop empty");}return elems.pop_back(); }template<typename T,typename CONT> T stack<T,CONT>::top()const{if(elems.empty()){throw std::out_of_range("stack<T>::top empty");}return elems.back(); }int main(){try{stack<int> intStack;stack<double,std::vector<double> > douStack;//注意,這里千萬不能寫下面的這一行代碼:// stack<double,std::vector<int> > douStack;intStack.push(1);std::cout<<intStack.top()<<std::endl;douStack.push(1.1);std::cout<<douStack.top()<<std::endl;}catch(std::exception const& ex){std::cerr<<ex.what()<<std::endl;return EXIT_FAILURE;}return 0; }我們使用
stack<double,std::vector<double> > douStack;來聲明了一個double stack,他的內部使用的是std:eque<>來管理。
轉載于:https://www.cnblogs.com/rollenholt/archive/2012/03/07/2383729.html
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的C++ template 学习归纳2的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 闭包是干嘛的
- 下一篇: form表单提交时,同一个名字的inpu