網(wǎng)站首頁 編程語言 正文
? ? 結(jié)合網(wǎng)上的資料,對函數(shù)模板的重載與實(shí)參推斷做一個總結(jié)。
函數(shù)模板的重載
? 當(dāng)需要對不同的類型使用同一種算法時,為了避免定義多個功能重復(fù)的函數(shù),可以使用模板。然而,并非所有的類型都使用同一種算法,有些特定的類型需要單獨(dú)處理,為了滿足這種需求,C++允許對函數(shù)模板進(jìn)行重載。
? 例如,當(dāng)交換基本類型和交換兩個數(shù)組時,雖然功能都是交換,但是使用的方法卻不相同,交換兩個數(shù)組唯一的辦法就是逐個交換所有的數(shù)組元素。
template<class T> void Swap(T &a, T &b){
T temp = a;
a = b;
b = temp;
}
template<typename T> void Swap(T a[], T b[], int len){
T temp;
for(int i=0; i<len; i++){
temp = a[i];
a[i] = b[i];
b[i] = temp;
}
}
函數(shù)模板的實(shí)參
? 在使用類模板創(chuàng)建對象時,需要顯式的指明實(shí)參,例如:
template<typename T1, typename T2> class Point;
Point<int, int> p1(10, 20); //在棧上創(chuàng)建對象
Point<char*, char*> *p = new Point<char*, char*>("東京180度", "北緯210度"); //在堆上創(chuàng)建對象
對于函數(shù)模板,調(diào)用函數(shù)時可以不顯式的指明實(shí)參,編譯器會自動推導(dǎo)出T的類型,例如:
//函數(shù)聲明
template<typename T> void Swap(T &a, T &b);
//函數(shù)調(diào)用
int n1 = 100, n2 = 200;
Swap(n1, n2);
float f1 = 12.5, f2 = 56.93;
Swap(f1, f2);
模板實(shí)參推斷過程中的類型轉(zhuǎn)換
普通函數(shù)調(diào)用時的類型轉(zhuǎn)換
- 算數(shù)轉(zhuǎn)換:例如 int 轉(zhuǎn)換為 float,char 轉(zhuǎn)換為 int,double 轉(zhuǎn)換為 int 等。
- 派生類向基類的轉(zhuǎn)換:也就是向上轉(zhuǎn)型,
- const 轉(zhuǎn)換:也即將非 const 類型轉(zhuǎn)換為?const 類型,例如將 char * 轉(zhuǎn)換為 const char *。
- 數(shù)組或函數(shù)指針轉(zhuǎn)換:如果函數(shù)形參不是引用類型,那么數(shù)組名會轉(zhuǎn)換為數(shù)組指針,函數(shù)名也會轉(zhuǎn)換為函數(shù)指針。
- 用戶自定的類型轉(zhuǎn)換。
例如:
void func1(int n, float f);
void func2(int *arr, const char *str);
int nums[5];
char *url = "http://c.biancheng.net";
func1(12.5, 45);
func2(nums, url);
? 對于 func1(),12.5 會從double
轉(zhuǎn)換為int
,45 會從int
轉(zhuǎn)換為float
;對于 func2(),nums 會從int [5]
轉(zhuǎn)換為int *
,url 會從char *
轉(zhuǎn)換為const char *
。
函數(shù)模板調(diào)用時的類型轉(zhuǎn)換
? 對于函數(shù)模板,類型轉(zhuǎn)換收到了更多的限制,僅能進(jìn)行[const 轉(zhuǎn)換]和[數(shù)組或函數(shù)指針轉(zhuǎn)換],其他都不能應(yīng)用于函數(shù)模板。
template<typename T> void func1(T a, T b);
template<typename T> void func2(T *buffer);
template<typename T> void func3(const T &stu);
template<typename T> void func4(T a);
template<typename T> void func5(T &a);
int name[20];
Student stu1("張華", 20, 96.5); //創(chuàng)建一個Student類型的對象
func1(12.5, 30); //Error
func2(name); //name的類型從 int [20] 換轉(zhuǎn)換為 int *,所以 T 的真實(shí)類型為 int
func3(stu1); //非const轉(zhuǎn)換為const,T 的真實(shí)類型為 Student
func4(name); //name的類型從 int [20] 換轉(zhuǎn)換為 int *,所以 T 的真實(shí)類型為 int *
func5(name); //name的類型依然為 int [20],不會轉(zhuǎn)換為 int *,所以 T 的真實(shí)類型為 int [20]
可以發(fā)現(xiàn),當(dāng)函數(shù)形參是引用類型時,數(shù)組不會轉(zhuǎn)換為指針。
template<typename T> void func(T &a, T &b);
int str1[20];
int str2[10];
func(str1, str2);
? 由于str1、str2的類型分別為int [20]和int [10],在函數(shù)調(diào)用過程中又不會轉(zhuǎn)換為指針,所以編譯器不知道應(yīng)該將T實(shí)例化為int [20]還是int [10],導(dǎo)致調(diào)用失敗
為函數(shù)模板顯式地指明實(shí)參
? 下面是一個實(shí)參推斷失敗的例子:
template<typename T1, typename T2> void func(T1 a){
T2 b;
}
func(10); //函數(shù)調(diào)用
func()有兩個類型參數(shù),分別是T1和T2,但是編譯器只能推斷出T1,不能推斷出T2,調(diào)用失敗
? 顯示指明的模板實(shí)參會按照從左到右的順序與對應(yīng)的模板參數(shù)匹配:第一個實(shí)參與第一個模板參數(shù)匹配,第二個實(shí)參與第二個模板參數(shù)匹配,只有尾部(最右)的類型參數(shù)的實(shí)參可以省略,而且前提是它們可以從傳遞給函數(shù)的實(shí)參中推斷出來。 例如:
template<typename T1, typename T2> void func(T2 a){
T1 b;
}
//函數(shù)調(diào)用
func<int>(10); //省略 T2 的類型
func<int, int>(20); //指明 T1、T2 的類型
顯式的指明實(shí)參時可以應(yīng)用正常的類型轉(zhuǎn)換
? 函數(shù)模板僅能進(jìn)行[ const 轉(zhuǎn)換 ]和[ 數(shù)組或函數(shù)指針轉(zhuǎn)換 ]兩種形式的類型轉(zhuǎn)換,但是當(dāng)我們顯式的指明類型參數(shù)的實(shí)參時,就可以使用正常的類型轉(zhuǎn)換了。例如:
template<typename T> void func(T a, T b);
func(10, 23.5); //Error
func<float>(20, 93.7); //Correct
? 在第二種調(diào)用形式中,我們已經(jīng)顯式地指明了T的類型為float,編譯器不會再為T的類型到底是int還是double而糾結(jié)了,所以可以從容地使用正常地類型轉(zhuǎn)換了。
原文鏈接:https://blog.csdn.net/weixin_45767431/article/details/127574432
相關(guān)推薦
- 2022-12-08 C語言如何實(shí)現(xiàn)成績等級判別_C 語言
- 2022-06-29 C#集合之自定義集合類_C#教程
- 2022-07-09 Python?對數(shù)字的千分位處理方式_python
- 2022-04-10 解決:git push error: failed to push some refs to
- 2022-06-22 C++詳細(xì)分析引用的使用及其底層原理_C 語言
- 2022-11-14 python?numpy查詢定位賦值數(shù)值所在行列_python
- 2022-07-10 簡單解析表格table標(biāo)簽的用法
- 2022-06-18 asp.net中Log4.net的工具類helper_實(shí)用技巧
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支