在早期的 C++ 學習中,我們為了交換不同類型變數的值(如 int、float、char、bool),通常會使用函數重載定義多個同名但參數列表不同的函數。雖然調用起來很方便,但本質上這是定義了多個函數體完全相同、僅數據類型不同的函數,造成了嚴重的代碼冗餘。
函數模板的出現正是為了解決這個問題。它允許我們建立一個通用函數,將數據類型參數化,並在編譯時根據實際傳入的參數自動推導具體類型,從而實現「寫一次,處處適用」。
在傳統函數中,數據的值可以通過參數傳遞,這稱為「值的參數化」。C++ 更進一步,允許數據的類型也通過參數傳遞——在定義時不指定具體類型,而是用一個虛擬類型(類型參數)佔位,編譯器在調用時根據實參自動推導真實類型。這就是「類型的參數化」。
值與類型是數據的兩大核心特徵,函數模板同時支持兩者的參數化,極大地提升了代碼的複用性與靈活性。
template <typename T>
返回值類型 函數名(形參列表) {
// 函數體中可使用類型參數 T
}
template 為關鍵字,緊跟尖括號 <>,內含類型參數聲明。typename 用於聲明類型參數(也可用 class 替代,兩者無區別)。整個 template<typename T> 稱為模板頭。
將前述四個重載 Swap() 壓縮為一個模板:
#include <iostream>
using namespace std;
template<typename T>
void Swap(T *a, T *b) {
T temp = *a;
*a = *b;
*b = temp;
}
int main() {
int n1 = 100, n2 = 200;
Swap(&n1, &n2);
cout << n1 << ", " << n2 << endl;
float f1 = 12.5, f2 = 56.93;
Swap(&f1, &f2);
cout << f1 << ", " << f2 << endl;
char c1 = 'A', c2 = 'B';
Swap(&c1, &c2);
cout << c1 << ", " << c2 << endl;
bool b1 = false, b2 = true;
Swap(&b1, &b2);
cout << b1 << ", " << b2 << endl;
return 0;
}
運行結果:
200, 100 56.93, 12.5 B, A 1, 0
利用 C++ 引用特性,可進一步簡化參數傳遞與調用語法:
template<typename T>
void Swap(T &a, T &b) {
T temp = a;
a = b;
b = temp;
}
// 調用時無需取址
Swap(n1, n2); // 直接傳遞變數
引用不僅使函數定義更簡潔,調用端也更直觀優雅。
模板可包含多個類型參數,以逗號分隔:
template <typename T1, typename T2>
返回值類型 函數名(形參列表) { ... }
函數模板也支援提前聲明,但模板頭與函數聲明/定義構成不可分割的整體,中間不能有分號:
// 聲明
template<typename T> T max(T a, T b, T c);
// 定義
template<typename T>
T max(T a, T b, T c) { // 此處無分號
T max_num = a;
if (b > max_num) max_num = b;
if (c > max_num) max_num = c;
return max_num;
}
typename 與 class 的區別兩者在模板參數聲明中完全等價。早期 C++ 僅支援 class,後引入 typename 以語義更清晰。現代代碼庫(如 STL)仍廣泛使用 class,建議兩者皆熟悉。
#include <iostream>
using namespace std;
template<typename T> T max(T a, T b, T c);
int main() {
int i1, i2, i3, i_max;
cin >> i1 >> i2 >> i3;
i_max = max(i1, i2, i3);
cout << "i_max=" << i_max << endl;
double d1, d2, d3, d_max;
cin >> d1 >> d2 >> d3;
d_max = max(d1, d2, d3);
cout << "d_max=" << d_max << endl;
long g1, g2, g3, g_max;
cin >> g1 >> g2 >> g3;
g_max = max(g1, g2, g3);
cout << "g_max=" << g_max << endl;
return 0;
}
template<typename T>
T max(T a, T b, T c) {
T max_num = a;
if (b > max_num) max_num = b;
if (c > max_num) max_num = c;
return max_num;
}
同一模板自動適配 int、double、long 等類型,展現泛型程式設計的強大威力。
template<typename T> 定義類型參數typename 與 class 可互換使用掌握函數模板是邁向 C++ 泛型程式設計與 STL 核心機制的關鍵基石。