C++函式模板即其例項化和具體化
阿新 • • 發佈:2021-10-20
函式模板
C++函式模板實質上是一個生成函式的方式,它的目的是減少重複勞動。在呼叫函式模板時,編譯器會生成一個函式例項,這種方式被稱為隱式例項化。當我們對不同型別的變數執行同樣的操作時,如果用函式過載,會麻煩很多。
例如,我們打一個絕對值函式
int fabs (int a)
{
return a>0?a:-a;
}
如果我們要對double型別也用絕對值函式,我們又得再打一個
double fabs (double a)
{
return a>0?a:-a;
}
但如果用函式模板,那麼就只用打一次,不僅int,double都可以用,long ,float甚至自定義的型別也可以用。
template <class T>
T fabs (T a)
{
return a>0?a:-a;
}
//定義兩個不同型別的模板這樣使用
template <class T1,class T2>
函式顯式例項化
即指示編譯器直接建立一個函式例項,上面說到,函式模板是一個生成函式的方式,顯式例項化就是告訴編譯器生成一個函式。
用法
template 函式型別 函式名 <模板型別>(模板型別);//尖括號可省略
eg:
template int fabs <int> (int a);
template int fabs (int a);
上述兩種寫法是一樣的
強制例項化
呼叫函式時可告訴編譯器使用哪種型別進行例項化,類似於變數的強制轉化。
用法舉例
fabs<long long>(a)
函式顯式具體化
當我們對不同型別要做不同處理方式時就用具體化。編譯器會對具體化的型別專門使用這個函式,類似於函式過載,不過這是對函式模板的特例化處理。
用法
template <> 函式型別 函式名 <模板型別>(模板型別)//尖括號可省略
{
函式內容
}
eg:
template <> float fabs <float> (float a)
{
return a+1;//隨便寫的內容
}
當我們呼叫函式時傳入的引數是兩個float時會使用上述函式
注意
template <> int fabs (int a)
{
return a+1;
}
template int fabs (int a);
但下面的程式碼可以
template int fabs (int a);//或者具體化
int fabs (int a)
{
return a+2;//隨便寫的
}
呼叫函式時,在變數型別匹配的上時,優先使用非模板型別的,也可這樣操作告訴編譯器使用模板型別的函式
fabs<>(a);
關鍵字\(decltype\)
當我們使用了複數個模板時,如
template <class T1,class T2>
T1 f (T1 a,T1 b);
如果我們新定義一個變數\(c,c=a+b\)
那麼\(c\)的型別是什麼呢,舉個例子
f(1,5.5)//①
f(5.5,1)//②
如果c是T1型別,那麼①中本應該是6.5變成了6,如果是T2型別,那麼②中則變成了6
而關鍵字\(decltype\)就能很好的解決這種問題
我們這麼宣告c變數,
decltype(a+b) c=a+b;
這表示定義一個型別和a+b一樣的變數
後置返回型別
只有\(decltype\)是不夠用的,這無法滿足對函式返回值的定義
於是有了這麼個語法
auto f (T1 a,T1 b) -> decltype (a+b)
這將返回值型別的宣告後置了,\(->decltype(a+b)\)被稱為後置返回型別