C++模板之函式模板
阿新 • • 發佈:2018-12-31
泛型程式設計
編寫與型別無關的邏輯程式碼,是程式碼複用的一種手段。模板是泛型程式設計的基礎
模板
代表一個函式家族,該函式與型別無關,在使用時被引數化,根據實參型別產生函式的特定型別版本(它本身不是類或函式)
模板函式的格式
模板的例項化
產生模板特定型別的過程稱為函式模板的例項化
template <typename T>
T Add(T left,T right)
{
return left + right;
}
int main()
{
Add(1,2);
Add(1.0,2.0);
Add('1' ,'1');
Add(1,1.0);//error:模板引數“T”不明確
//模板函式不會進行型別轉換
Add<int>(1, '1');//顯式例項化
Add<double>(1, 1.0);
Add(1,(int) 1.0);//隱式例項化
return 0;
}
模板的實參推演
從函式實參確定模板形參型別和值得過程稱為模板實參推斷
型別形參轉換
一般不會轉換實參已匹配以有的例項化,相反會產生新的例項;
編譯器只會執行兩種轉換:1.const轉換;2.陣列或函式到指標的轉換
const轉換
接收const引用或const指標的函式可以分別用非const物件的引用或者指標來呼叫
陣列或函式到指標的轉換
如果模板形參不是引用型別,則對陣列或函式型別的實參應用常規指標轉換。陣列實參將當做指向其第一個元素的指標,函式實參當做指向函式型別的指標
模板形參
- 模板型別引數
typedef double T;
//模板形參的名字在同一模板中只能使用一次
template <typename T, typename T>// error C2991: 重定義 模板 引數“T”
//所有模板形參前必須加上class/typename關鍵字修飾
template <typename T,U>//error C2061: 語法錯誤: 識別符號“U”
template <typename T = int> //可以指定預設的模板實參
T Add(T left=1, T right=2 )//預設的呼叫引數
{
cout << "T type = " << typeid(T).name() << endl;//列印模板引數T的型別
return left + right;
}
T val;//全域性變數
int main()
{
Add();
cout << "T type = " << typeid(T).name() << endl;//列印全域性變數的型別
return 0;
}
模板形參的名字只能在模板形參之後到模板宣告或定義的末尾使用
- 非模板型別引數
模板內部定義的常量
template <typename T = int ,int N = 10> //N:非模板型別引數
void Funtest(T(&_array)[N]) //陣列引用
{
for (int i = 0; i < N; ++i)
{
_array[i] = 0;
}
}
int main()
{
const int c = 3;
int a[4];
int b[c + 1];
Funtest(a);
Funtest(b);
return 0;
}
模板函式和同名非模板函式
int Max(const int& a, const int& b) //同名的非模板函式和模板函式可以同時存在
{
return a > b ? a : b;
}
template <typename T>
T Max(const T& a,const T& b)
{
return a > b ? a : b;
}
template <typename T1, typename T2>
T1 Max(const T1& a, const T2& b)
{
return a > b ? a : b;
}
int main()
{
Max(1, 2);//優先呼叫非模板函式
Max<>(1, 2);//顯示指定,只能呼叫模板
Max(1, 2.0);//優先呼叫優化模板template <typename T1, typename T2>
return 0;
}
模板特化
- 特化格式
template <typename T>//模板例項
int compare(T a, T b)//比較了地址
{
if (a < b)
return -1;
if (a>b)
return 1;
return 0;
}
template <>//模板特化 在模板例項之後
//特化的宣告必須與特定的模板相匹配
//int compare<const char*>(char* p1, char* p2)//error :不是函式模板的專用化
int compare<const char*>(const char* p1, const char* p2)
{
return strcmp(p1,p1);
}
int main()
{
char* p1 = "abcd";
char* p2 = "abce";
const char* p3 = "abcd";
const char* p4 = "abce";
cout << compare(p1, p2) << endl;
cout << compare(p3, p4) << endl;
return 0;
}
模板過載
template <typename T>
T Max(const T& a, const T& b)
{
return a > b ? a : b;
}
template <typename T>
T Max(const T& a, const T& b, const T& c)//過載
{
return Max(Max(a, b), c);
}
int main()
{
Max(1, 2);
Max(1, 2, 4);
return 0;
}