void Swap(int & x, int & y) { int tmp = x; x = y; y = tmp; }
void Swap (double & xr double & y) { double tmp = x; x = y; y = tmp; }
template <class 型別引數1, class型別引數2, ...>
返回值型別 模板名(形參表)
{
函數體
}
template <typename 型別引數1, typename 型別引數2, ...>
函數模板看上去就像一個函數。前面提到的 Swap 模板的寫法如下:template <class T> void Swap(T & x, T & y) { T tmp = x; x = y; y = tmp; }T 是型別引數,代表型別。編譯器由模板自動生成函數時,會用具體的型別名對模板中所有的型別引數進行替換,其他部分則原封不動地保留。同一個型別引數只能替換為同一種型別。編譯器在編譯到呼叫函數模板的語句時,會根據實參的型別判斷該如何替換模板中的型別引數。
#include <iostream> using namespace std; template<class T> void Swap(T & x, T & y) { T tmp = x; x = y; y = tmp; } int main() { int n = 1, m = 2; Swap(n, m); //編譯器自動生成 void Swap (int &, int &)函數 double f = 1.2, g = 2.3; Swap(f, g); //編譯器自動生成 void Swap (double &, double &)函數 return 0; }編譯器在編譯到
Swap(n, m);
時找不到函數 Swap 的定義,但是發現實參 n、m 都是 int 型別的,用 int 型別替換 Swap 模板中的 T 能得到下面的函數:
void Swap (int & x, int & y) { int tmp = x; x = y; y = tmp; }該函數可以匹配
Swap(n, m);
這條語句。於是編譯器就自動用 int 替換 Swap 模板中的 T,生成上面的 Swap 函數,將該 Swap 函數的原始碼加入程式中一起編譯,並且將Swap(n, m);
編譯成對自動生成的 Swap 函數的呼叫。Swap(f, g);
時會用 double 替換 Swap 模板中的 T,自動生成以下 Swap 函數:
void Swap(double & x, double & y) { double tmp = x; x = y; y = tmp; }然後再將
Swap(f, g);
編譯成對該 Swap 函數的呼叫。模板名<實際型別引數1, 實際型別引數2, ...>
的方式告訴編譯器應該如何範例化模板函數。例如下面的程式:#include <iostream> using namespace std; template <class T> T Inc(int n) { return 1 + n; } int main() { cout << Inc<double>(4) / 2; return 0; }
Inc<double>(4)
指明了此處範例化的模板函數原型應為:
double Inc(double);
編譯器不會因為實參 4 是 int 型別,就生成原型為 int Inc(int) 的函數。因此,上面程式輸出的結果是 2.5 而非 2。template <class Tl, class T2> T2 print(T1 argl, T2 arg2) { cout << arg1 << " " << arg2 << endl; return arg2; }
#include <iostream> using namespace std; template <class T> T MaxElement(T a[], int size) //size是陣列元素個數 { T tmpMax = a[0]; for (int i = 1; i < size; ++i) if (tmpMax < a[i]) tmpMax = a[i]; return tmpMax; } class CFraction //分數類 { int numerator; //分子 int denominator; //分母 public: CFraction(int n, int d) :numerator(n), denominator(d) { }; bool operator <(const CFraction & f) const {//為避免除法產生的浮點誤差,用乘法判斷兩個分數的大小關係 if (denominator * f.denominator > 0) return numerator * f.denominator < denominator * f.numerator; else return numerator * f.denominator > denominator * f.numerator; } bool operator == (const CFraction & f) const {//為避免除法產生的浮點誤差,用乘法判斷兩個分數是否相等 return numerator * f.denominator == denominator * f.numerator; } friend ostream & operator <<(ostream & o, const CFraction & f); }; ostream & operator <<(ostream & o, const CFraction & f) {//過載 << 使得分數物件可以通過cout輸出 o << f.numerator << "/" << f.denominator; //輸出"分子/分母" 形式 return o; } int main() { int a[5] = { 1,5,2,3,4 }; CFraction f[4] = { CFraction(8,6),CFraction(-8,4), CFraction(3,2), CFraction(5,6) }; cout << MaxElement(a, 5) << endl; cout << MaxElement(f, 4) << endl; return 0; }編譯到第 41 行時,根據實參 a 的型別,編譯器通過 MaxElement 模板自動生成了一個 MaxElement 函數,原型為:
int MaxElement(int a[], int size);
編譯到第 42 行時,根據 f 的型別,編譯器又生成一個 MaxElement 函數,原型為:CFraction MaxElement(CFraction a[], int size);
在該函數中,用到了<
比較兩個 CFraction 物件的大小。如果沒有對<
進行適當的過載,編譯時就會出錯。