模板函數:機制介紹
在很多時候,我們需要對不同的數據類型做一些操作,但是這些操作是相同的,比如求取一個數組中的最大元素,我們只需:
for(int i=0; i<arr.size(); i++)
if(arr[i] > max_val) max_val = arr[i];
可是面對不同的數據類型,我們需要實現不同的函數,比如下面我們需要實現兩個函數來選擇int
或者double
數組中的最大值,非常麻煩
int array_max(vector<int> arr)
{
int max_val = arr[0];
for(int i=0; i<arr.size(); i++)
if(arr[i] > max_val) max_val = arr[i];
return max_val;
}
double array_max(vector<double> arr)
{
double max_val = arr[0];
for(int i=0; i<arr.size(); i++)
if(arr[i] > max_val) max_val = arr[i];
return max_val;
}
而模板函數機制則提供了一種靈活的組織方式,我們不需要告訴函數具體的形參數據類型,而只用專注於函數功能的實現
注意:在python中這種機制被很好的執行,如下是python的數組求最大:
def array_max(arr):
val = arr[0]
for item in arr:
if item > val:
val = item
return val
你看,任何數據類型,只要支持[]
下標運算和>
比較運算,都可以使用這個函數,這就是【模板函數】機制在python理解下的實現
模板函數:實現
在實現函數之前,添加關鍵詞:template<class 類型>
比如下面這個例子,可實現傳入任意支持 ++
運算的數據類型(包括重載了++算符的自定義數據類型),並且對其++
可以簡單的認爲:T就是傳入數據類型的別名,真正執行的時候,會把T換成傳入的數據類型,比如傳入int,那麼所有的T替換成int
template<class T>
T add(T data)
{
data++;
return data;
}
多個同類形參:比如我們實現交換函數swap,交換兩個同類型的變量
template<class T>
void my_swap(T& o1, T& o2)
{
T temp = o1;
o1 = o2;
o2 = temp;
}
多類型多變量:template內容必須按照形參表順序,比如我們定義函數my_print
來輸出兩種不同類型的變量
template<class T1, class T2>
void my_print(T1 o1, T2 o2)
{
cout<<o1<<" "<<o2<<endl;
}
值得注意的是,template<>
裏面的內容必須和函數的形參表完全一一對應,因爲編譯器會按實際調用時傳入的數據類型,一一對應他們的別名
錯誤示範:
template<class T1, class T2, class T3>
void add_dif(T2 a, T3 b, T1 aaa)
{
}
// main函數:
add_dif(1.23, 4.77, 1);
// 編譯器拋出錯誤:
[Error] in passing argument 1 of void add_dif(T2, T3, T1)
[with T1 = int; T2 = double; T3 = double]
正確寫法:
template<class T1, class T2, class T3>
void add_dif(T1 a, T2 b, T3 aaa)
{
}
注意如果函數返回值要返回模板類型T的數據,那麼也要在形參表中添加T,即使函數沒有用到,但爲了編譯通過並且順利建立別名映射,必須添加
代碼
首先使用模板函數add,將任意數據類型++後輸出
然後使用模板函數my_swap交換兩個任意的同類數據
然後使用模板函數my_print打印兩個任意的數據類型(可不同也可相同)
#include <bits/stdc++.h>
using namespace std;
template<class T>
T add(T data)
{
data++;
return data;
}
template<class T>
void my_swap(T& o1, T& o2)
{
T temp = o1;
o1 = o2;
o2 = temp;
}
template<class T1, class T2>
void my_print(T1 o1, T2 o2)
{
cout<<o1<<" "<<o2<<endl;
}
int main()
{
cout<<add(114)<<endl;
cout<<add(123.45)<<endl;
cout<<add('a')<<endl<<endl;
string s1="world", s2="hello";
my_swap(s1, s2);
cout<<s1<<" -- "<<s2<<endl<<endl;
my_print(123, "zsbd");
return 0;
}