網站首頁 編程語言 正文
? 本文結合網上的資料對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*代表的是第一個類型參數,還是第二個類型參數。
原文鏈接:https://blog.csdn.net/weixin_45767431/article/details/127577583
- 上一篇:qt輸出自定義的pdf文件源碼詳解
- 下一篇:C++ 函數模板的重載與實參推斷
相關推薦
- 2022-03-28 Python垃圾回收及Linux?Fork_python
- 2022-05-27 Flutter狀態管理Bloc之定時器示例_Android
- 2022-09-04 django連接數據庫獲取數據的簡單步驟記錄_python
- 2022-10-18 C/C++函數指針深入探究_C 語言
- 2022-12-23 Android入門之SubMenu的實現詳解_Android
- 2022-07-01 Android?TextView跑馬燈實現原理及方法實例_Android
- 2022-04-30 詳解Matlab如何繪制小提琴圖_C 語言
- 2022-08-01 使用docker環境變量動態配置nginx的問題小結_docker
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支