日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++ 模板的显式具体化

發布時間:2024/3/26 c/c++ 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++ 模板的显式具体化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? 本文結合網上的資料對C++模板的顯式具體化做了一個總結。

? 對于模板,模板中的語句(函數體或者類)不一定能適應所有的類型,可能會有個別的類型沒有意義,或者會導致語法錯誤。我們希望模板能夠針對某種具體的類型使用不同的算法,可以使用顯式具體化。

函數模板的顯式具體化

typedef struct{string name;int age;float score; } STU; //函數模板 template<class T> const T& Max(const T& a, const T& b); //函數模板的顯示具體化(針對STU類型的顯示具體化) template<> const STU& Max<STU>(const STU& a, const STU& b);template<class T> const T& Max(const T& a, const T& b){return a > b ? a : b; } template<> const STU& Max<STU>(const STU& a, const STU& b){return a.score > b.score ? a : b; }

? ? Max<STU>中的STU表明了要將類型參數T具體化為STU類型,原來使用T的位置都應該使用STU替換,包括返回值類型、形參類型、局部變量的類型。Max只有一個類型參數T,并且已經被具體化為STU了,這樣整個模板就不再有類型參數了,類型參數列表也就為空了,所以模板頭應該寫作template<>。另外,Max<STU>中的STU是可選的,因為函數的形參已經表明,這是 STU 類型的一個具體化,編譯器能夠逆推出 T 的具體類型。簡寫后的函數聲明為:

template<> const STU& Max(const STU& a, const STU& b);

??在調用函數時,顯示具體化優先于常規模板,而非模板函數優先于顯示具體化和常規模板。

類模板的顯式具體化

?如果一個可以輸出不同類型坐標的類模板,希望當 x 和 y 都是字符串時以|為分隔,是數字或者其中一個是數字時才以逗號,為分隔,可以使用顯示具體化技術對字符串類型的坐標做特殊處理。

//類模板 template<class T1, class T2> class Point{ public:Point(T1 x, T2 y): m_x(x), m_y(y){ } public:T1 getX() const{ return m_x; }void setX(T1 x){ m_x = x; }T2 getY() const{ return m_y; }void setY(T2 y){ m_y = y; }void display() const; private:T1 m_x;T2 m_y; }; template<class T1, class T2> //這里要帶上模板頭 void Point<T1, T2>::display() const{cout<<"x="<<m_x<<", y="<<m_y<<endl; } //類模板的顯示具體化(針對字符串類型的顯示具體化) template<> class Point<char*, char*>{ public:Point(char *x, char *y): m_x(x), m_y(y){ } public:char *getX() const{ return m_x; }void setX(char *x){ m_x = x; }char *getY() const{ return m_y; }void setY(char *y){ m_y = y; }void display() const; private:char *m_x; //x坐標char *m_y; //y坐標 }; //這里不能帶模板頭template<> void Point<char*, char*>::display() const{cout<<"x="<<m_x<<" | y="<<m_y<<endl; } int main(){( new Point<int, int>(10, 20) ) -> display();( new Point<int, char*>(10, "東京180度") ) -> display();( new Point<char*, char*>("東京180度", "北緯210度") ) -> display();return 0; }

運行結果:

x=10, y=20
x=10, y=東京180度
x=東京180度 | y=北緯210度

??Point<char*, char*>表明了要將類型參數 T1、T2 都具體化為char*類型,原來使用 T1、T2 的位置都應該使用char*替換。Point 類有兩個類型參數 T1、T2,并且都已經被具體化了,所以整個類模板就不再有類型參數了,模板頭應該寫作template<>。當在類的外部定義成員函數時,普通類模板的成員函數前面要帶上模板頭,而具體化的類模板的成員函數前面不能帶模板頭。

部分顯式具體化

??C++ 還允許只為一部分類型參數提供實參,這稱為部分顯式具體化。部分顯式具體化只能用于類模板,不能用于函數模板。

??仍然以 Point 為例,假設我現在希望“只要橫坐標 x 是字符串類型”就以|來分隔輸出結果,而不管縱坐標 y 是什么類型,這種要求就可以使用部分顯式具體化技術來滿足:

//類模板 template<class T1, class T2> class Point{ public:Point(T1 x, T2 y): m_x(x), m_y(y){ } public:T1 getX() const{ return m_x; }void setX(T1 x){ m_x = x; }T2 getY() const{ return m_y; }void setY(T2 y){ m_y = y; }void display() const; private:T1 m_x;T2 m_y; }; template<class T1, class T2> //這里需要帶上模板頭 void Point<T1, T2>::display() const{cout<<"x="<<m_x<<", y="<<m_y<<endl; } //類模板的部分顯示具體化 template<typename T2> class Point<char*, T2>{ public:Point(char *x, T2 y): m_x(x), m_y(y){ } public:char *getX() const{ return m_x; }void setX(char *x){ m_x = x; }T2 getY() const{ return m_y; }void setY(T2 y){ m_y = y; }void display() const; private:char *m_x; //x坐標T2 m_y; //y坐標 }; template<typename T2> //這里需要帶上模板頭 void Point<char*, T2>::display() const{cout<<"x="<<m_x<<" | y="<<m_y<<endl; } int main(){( new Point<int, int>(10, 20) ) -> display();( new Point<char*, int>("東京180度", 10) ) -> display();( new Point<char*, char*>("東京180度", "北緯210度") ) -> display();return 0; }

運行結果:
x=10, y=20
x=東京180度 | y=10
x=東京180度 | y=北緯210度

? 模板頭template<typename T2>中聲明的是沒有被具體化的類型參數;類名Point<char*, T2>列出了所有類型參數,包括未被具體化的和已經被具體化的。類名后面之所以要列出所有的類型參數,是為了讓編譯器確認“到底是第幾個類型參數被具體化了”,如果寫作template<typename T2> class Point<char*>,編譯器就不知道char*代表的是第一個類型參數,還是第二個類型參數。

總結

以上是生活随笔為你收集整理的C++ 模板的显式具体化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。