您好,登錄后才能下訂單哦!
本篇內容介紹了“C++函數模板如何使用”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
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); //#1 template<typename T> void Swap(T *a ,T *b,int n);//#2 最后一個參數是具體類型 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; } }
某些時候,類型T的相應操作只適用于數組,如果T為結構體則模板函數便不成立
同樣,如if(a>b)
,如果T為結構,則>便不成立
解決方案:
重載運算符號
為特定類型提供具體化模板定義
當編譯器找到與函數調用匹配的具體化定義時,將使用該定義,不再尋找模板。
對于給定的函數名,可以有非模板函數、模板函數和顯示具體化模板函數以及各自的重載版本。
顯示具體化的原型和定義以template<>
開頭,并通過名稱來指出類型
調用順序是:非模板函數>具體化模板函數>模板函數
void Swap(job& ,job&); template <typename T> void Swap(T&,T&); template<> void Swap<job>(job& ,job&);//顯示具體化 //Swap<job>中<job>是可選的,因為函數的參數類型表明,這是job的一個具體化,所以也可以這樣寫: template<> void Swap(job& ,job&);
注意:函數模板并不會生成函數定義,他只是生成一個用于生成函數定義的方案,編譯器使用模板為特定的類型生成函數定義時,得到的是模板實例。
template<typename T> void Swap(T &a ,T &b); int a =10,b=20; Swap(a,b);//因為提供了int類型的參數,所以自動生成了int類型的模板實例。這樣是==隱式實例化== //也可以直接命令編譯器創建特定的實例 //顯示實例化 template void Swap<int>(int &,int &);//使用Swap()模板生成int類型的函數定義 //顯示具體化 template<> void Swap<int>(int& ,int&); template<> void Swap(int& ,int&); //區別在于:具體化是不使用Swap()模板函數生成函數定義,而是使用專門為int類型顯示定義的函數定義 //簡單的理解,具體化是對函數的聲明,而實例化是對模板函數的使用
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)不匹配,因為一個是int一個是double //通過Add<double>實例化,可強制將m轉為double //但是同樣的對Swap便不能成功,因為Swap中使用的是引用類型 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);//隱式實例化 job n,m; Swap(n,m);//顯示具體化 char g,h; Swap(g,h);//顯示實例化 }
template<class T1,class T2> void fun(T1 x,T2 y) { ?type? s=x+y; //因為是模板函數,此時?type?類型不確定 }
C++11增加decltype
關鍵字
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沒有用括號括起來,則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是一個函數調用,則var與返回值類型相同。并不會實際調用函數,編譯器通過查看原型來確定返回值類型
3.如果expression是一個左值,則var為指向其類型的引用。常見的情況如下:
double x = 4.5; decltype((x)) r = x;//r是double&類型 decltype(x) r = x;//r是double類型 //括號不會改變expression的值和左值性 //可理解為加括號僅僅是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個int的和
如果多次聲明,可以結合typedef
和decltype
typedef decltype(x+y) xytype; xytype z = x+y; xytype arr[10];
但是某些需定義返回值類型的函數模板任然不能得到解決,如:
template<class T1,class T2> ?type? fun(T1 x,T2 y) //此時無法確定類型 { return x+y; }
C++新增語法auto h(int x,float y) -> double
,這稱為后置返回類型,auto是一個占位符
template<class T1,class T2> auto fun(T1 x,T2 y)->decltype(x+y) //后置類型使用decltype { return x+y; }
“C++函數模板如何使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。