C++學(xué)習(xí)之函數(shù)模板的使用詳解
C++函數(shù)模板
template<typename T>
void Swap(T &a ,T &b)
{
T temp;
temp = a;
a = b;
b = temp;
}
在使用模板函數(shù)時(shí),編譯器根據(jù)實(shí)際的類型生成相應(yīng)的函數(shù)定義。
重載的模板
并非所有的類型都使用相同的算法,可以像重載常規(guī)函數(shù)那樣重載模板函數(shù)定義。
template<typename T>
void Swap(T &a ,T &b); //#1
template<typename T>
void Swap(T *a ,T *b,int n);//#2 最后一個(gè)參數(shù)是具體類型
int main()
{
int i =10,j=20;
Swap(i,j);//使用#1
const int Lim = 8;
int d1[Lim]={0,1,2,3,4,5,6,7};
int d2[Lim]={7,6,5,4,3,2,1,0};
Swap(d1,d2,Lim);//使用#2
}
template<typename T>
void Swap(T &a ,T &b)
{
T temp;
temp = a;
a = b;
b = temp;
}
template<typename T>
void Swap(T *a ,T *b,int n)
{
T temp;
for(int i=0;i<n;i++)
{
temp =a[i];
a[i]=b[i];
b[i]=temp;
}
}
模板局限性
某些時(shí)候,類型T的相應(yīng)操作只適用于數(shù)組,如果T為結(jié)構(gòu)體則模板函數(shù)便不成立
同樣,如if(a>b),如果T為結(jié)構(gòu),則>便不成立
解決方案:
- 重載運(yùn)算符號(hào)
- 為特定類型提供具體化模板定義
顯示具體化
當(dāng)編譯器找到與函數(shù)調(diào)用匹配的具體化定義時(shí),將使用該定義,不再尋找模板。
- 對于給定的函數(shù)名,可以有非模板函數(shù)、模板函數(shù)和顯示具體化模板函數(shù)以及各自的重載版本。
- 顯示具體化的原型和定義以
template<>開頭,并通過名稱來指出類型 - 調(diào)用順序是:非模板函數(shù)>具體化模板函數(shù)>模板函數(shù)
void Swap(job& ,job&); template <typename T> void Swap(T&,T&); template<> void Swap<job>(job& ,job&);//顯示具體化 //Swap<job>中<job>是可選的,因?yàn)楹瘮?shù)的參數(shù)類型表明,這是job的一個(gè)具體化,所以也可以這樣寫: template<> void Swap(job& ,job&);
實(shí)例化和具體化
注意:函數(shù)模板并不會(huì)生成函數(shù)定義,他只是生成一個(gè)用于生成函數(shù)定義的方案,編譯器使用模板為特定的類型生成函數(shù)定義時(shí),得到的是模板實(shí)例。
template<typename T> void Swap(T &a ,T &b); int a =10,b=20; Swap(a,b);//因?yàn)樘峁┝薸nt類型的參數(shù),所以自動(dòng)生成了int類型的模板實(shí)例。這樣是==隱式實(shí)例化== //也可以直接命令編譯器創(chuàng)建特定的實(shí)例 //顯示實(shí)例化 template void Swap<int>(int &,int &);//使用Swap()模板生成int類型的函數(shù)定義 //顯示具體化 template<> void Swap<int>(int& ,int&); template<> void Swap(int& ,int&); //區(qū)別在于:具體化是不使用Swap()模板函數(shù)生成函數(shù)定義,而是使用專門為int類型顯示定義的函數(shù)定義 //簡單的理解,具體化是對函數(shù)的聲明,而實(shí)例化是對模板函數(shù)的使用
template<typename T>
T Add(T a,T b)
{
return a+b;
}
int m=6;
double x=10.5;
Add<double>(x,m); //與Add(x,m)不匹配,因?yàn)橐粋€(gè)是int一個(gè)是double
//通過Add<double>實(shí)例化,可強(qiáng)制將m轉(zhuǎn)為double
//但是同樣的對Swap便不能成功,因?yàn)镾wap中使用的是引用類型
Swap<double>(m,x);//double& 不能指向int
//使用案例
template <typename T>
void Swap(T &,T &);
template<> void Swap<job>(job&,job&);//具體化
int mian()
{
template void Swap<char>(char& ,char&);
short a,b;
Swap(a,b);//隱式實(shí)例化
job n,m;
Swap(n,m);//顯示具體化
char g,h;
Swap(g,h);//顯示實(shí)例化
}
模板函數(shù)類型的確定
template<class T1,class T2>
void fun(T1 x,T2 y)
{
?type? s=x+y; //因?yàn)槭悄0搴瘮?shù),此時(shí)?type?類型不確定
}
C++11增加decltype關(guān)鍵字
template<class T1,class T2>
void fun(T1 x,T2 y)
{
decltype(x+y) s=x+y; //s類型與x+y的類型一致
}
使用decltype(expression) var 的步驟:
1.如果expression沒有用括號(hào)括起來,則var與expression類型相同,包括const等限定符
double x =5.5; double& z =x; const double* pd; decltype(x) w; //w為double類型 decltype(z) u; //u為double& 類型 decltype(pd) v; //v為const double* 類型
2.如果expression是一個(gè)函數(shù)調(diào)用,則var與返回值類型相同。并不會(huì)實(shí)際調(diào)用函數(shù),編譯器通過查看原型來確定返回值類型
3.如果expression是一個(gè)左值,則var為指向其類型的引用。常見的情況如下:
double x = 4.5; decltype((x)) r = x;//r是double&類型 decltype(x) r = x;//r是double類型 //括號(hào)不會(huì)改變expression的值和左值性 //可理解為加括號(hào)僅僅是decltype聲明引用的一種方式
4.如果前3條都不滿足,則var與expression類型相同
int j=3; int &k=j; int &n=j; decltype(j+6) x; //x是int decltype(k+n) y;//y是int ,雖然k和n是引用,但是k+n不是引用是2個(gè)int的和
如果多次聲明,可以結(jié)合typedef和decltype
typedef decltype(x+y) xytype; xytype z = x+y; xytype arr[10];
但是某些需定義返回值類型的函數(shù)模板任然不能得到解決,如:
template<class T1,class T2>
?type? fun(T1 x,T2 y) //此時(shí)無法確定類型
{
return x+y;
}
C++新增語法auto h(int x,float y) -> double,這稱為后置返回類型,auto是一個(gè)占位符
template<class T1,class T2>
auto fun(T1 x,T2 y)->decltype(x+y) //后置類型使用decltype
{
return x+y;
}到此這篇關(guān)于C++學(xué)習(xí)之函數(shù)模板的使用詳解的文章就介紹到這了,更多相關(guān)C++函數(shù)模板內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++?JSON庫?nlohmann::basic_json::accept的用法解析
nlohmann::basic_json::accept 是 Nlohmann JSON 庫中的一個(gè)方法,它用于檢查一個(gè)字符串是否可以解析為有效的 JSON,這篇文章主要介紹了C++?JSON庫nlohmann::basic_json::accept的用法,需要的朋友可以參考下2023-06-06
C++實(shí)現(xiàn)數(shù)字轉(zhuǎn)換為十六進(jìn)制字符串的方法
這篇文章主要介紹了C++實(shí)現(xiàn)數(shù)字轉(zhuǎn)換為十六進(jìn)制字符串的方法,涉及C++操作數(shù)字與字符串轉(zhuǎn)換的相關(guān)技巧,需要的朋友可以參考下2015-06-06
OpenCV圖像算法實(shí)現(xiàn)圖像切分圖像合并示例
這篇文章主要為大家介紹了python圖像算法OpenCV實(shí)現(xiàn)圖像切分圖像合并操作示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
c++與python實(shí)現(xiàn)二分查找的原理及實(shí)現(xiàn)
本文介紹了c++與python實(shí)現(xiàn)二分查找的原理及實(shí)現(xiàn),二分查找指首先將數(shù)組中間值和目標(biāo)值進(jìn)行比較,如果相等則返回;如果不相等,則選擇中間值左邊的一半或者右邊的一半進(jìn)行比較;不斷重復(fù)直到檢索完畢,下文相關(guān)資料需要的朋友可以參考一下2022-03-03
C++?超詳細(xì)分析數(shù)據(jù)結(jié)構(gòu)中的時(shí)間復(fù)雜度
時(shí)間復(fù)雜度一般指時(shí)間復(fù)雜性。?在計(jì)算機(jī)科學(xué)中,時(shí)間復(fù)雜性,又稱時(shí)間復(fù)雜度,算法的時(shí)間復(fù)雜度是一個(gè)函數(shù),它定性描述該算法的運(yùn)行時(shí)間2022-03-03
C++中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式的方法
這篇文章主要介紹了C++中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04
你不知道的C++中namespace和using的用法實(shí)例
在C++語言編寫的程序中,變量和函數(shù)等的作用范圍是有一定限制的,下面這篇文章主要給大家介紹了一些你不知道的C++中namespace和using的用法,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-12-12

