一、泛型编程
如何实现一个通用的交换函数呢?
void Swap(int& left, int& right) {
int temp = left;
left = right;
right = temp;
}
void Swap(double& left, double& right) {
double temp = left;
left = right;
right = temp;
}
void Swap(char& left, char& right) {
char temp = left;
left = right;
right = temp;
}
函数重载虽然可以实现,但存在以下问题:
- 代码复用率低,如果出现新类型就要增加对应函数。
- 代码的可维护性较低,一个错误可能会让所有重载出错。
泛型解决的是:告诉编译器一个模子,让它根据不同类型生成不同的对象
如果在 C++ 中,能够存在这样一个模具,通过给这个模具中填充不同材料(类型),来获得不同材料的铸件(即生成具体类型的代码),那将会节省许多时间。巧的是前人早已将树栽好,我们只需在此乘凉。
泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。
二、函数模板
概念
函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。
格式:template<class 模板> 或 template<typename 模板>
template<typename T>
void Swap(T& left, T& right) {
T temp = left;
left = right;
right = temp;
}
注意:typename 是用来定义模板参数的关键字,也可以使用 class(切记:不能使用 struct 代替 class)。
原理
函数模板是一个蓝图,它本身并不是函数,是编译器使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器。
在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。比如:当用 double 类型使用函数模板时,编译器通过对实参类型的推演,将 T 确定为 类型,然后产生一份专门处理 类型的代码。


