泛型程式設計
- Generic Programming
- 算法實作時不指定具體要操作的資料的類型,适用于多種資料結構; 通俗的來說,算法實作一遍,但适用于多種資料結構;
- 大量編寫模闆,使用模闆的程式設計:
- 函數模闆
- 類模闆
- 優勢:減少重複代碼的編寫;
函數模闆
- 定義
template<class 類型參數1, class 類型參數2, ...>
傳回值類型 模闆名(形參表)
{
函數體
}
- 例:交換函數
template <class T>
void swap(T &x, T &y)
{
T tmp = x;
a = b;
b = tmp;
}
// 編譯器會自動生成相應的函數
int main() {
int n = 1, m = 2;
Swap(n,m);
//編譯器自動生成void Swap(int &, int &)函數
double f = 1.2, g =2.3;
//編譯器自動生成void Swap(double &,double &)函數,并進行調用;
Swap(f,g);
return 0;
}
Notes:
- 函數模闆中可以有不止一個類型參數,即函數類型不一緻。如下面的例子:
template<class T1, class T2>//通過定義不同類型的模闆 T2 print(T1 arg1, T2 arg2) { cout<<arg1<<" "<<arg2<<endl; return arg2; //傳回值也是T2類型 }
- 函數模闆可以重載,隻要形參表不同即可。如下面的例子:
template<class T1,class T2> void print(T1 arg1,T2 arg2) {} template<class T> void print(T arg1, T arg2) {}
編譯器比對函數的順序
- Step 1: 先找參數完全比對的普通函數(非由模闆執行個體化而得的函數)
- Step 2: 再找參數完全比對的模闆函數
- Step 3: 再找實參經過自動類型轉換後能夠比對的普通函數
- Step 4: 上面的都找不到, 則報錯
下面我們用一個例子來說明,模闆調用順序:
template <class T>
T Max(T a, T b) {
cout<<"Template Max 1"<<endl;
return 0;
}
template <class T, class T2>
T Max(T a, T2 b) {
cout<<"Template Max 2"<<endl;
return 0;
}
double Max(double a,double b) {//普通函數
cout<<"MyMax"<<endl;
return 0;
}
int main() {
int i = 4, j = 5;
Max(1.2,3.4);//調用Max(double, double)
Max(i,j);
// i j 為int類型,沒有普通函數能夠完全比對
//調用第一個T Max(T a,T b)模闆生成的函數
Max(1.2,3);//調用第二個T Max(T a, T2 b)模闆生成的函數
return 0;
}
*注意
指派相容原則引起函數模闆中類型參數的二義性
template<class T>
T myFunction(T arg1, T arg2)
{
cout<<arg1<<“ ”<<arg2<<“\n”;
return arg1; }
…
myFunction(5, 7); //ok: replace T with int
myFunction(5.8, 8.4); //ok: replace T with double
myFunction(5, 8.4); //error: replace T with int or double?
對于這種情況,我們可以在函數模闆中使用多個類型參數, 可以有效地避免二義性
Reference
- [1] https://www.coursera.org/learn/cpp-chengxu-sheji/
- [2] https://github.com/chiuchiuuu/programming-and-algorithm