文章目录
- 🌈 Ⅰ 泛型编程
- 🌈 Ⅱ 函数模板
- 1. 函数模板概念
- 2. 函数模板格式
🌈 Ⅰ 泛型编程
1. 泛型编程引入
- 假设当前要实现交换两个变量的功能,那么就得根据实参的数据类型来对该函数进行重载。
- 重载的函数只是数据类型不同而已,但是一旦要交换新类型的变量就得多重载一份函数。
- 此时就需要使用 泛型编程 来将繁琐的流水线编程简单化。
void Swap(int& x, int& y)
{
int tmp = x;
x = y;
y = tmp;
}
void Swap(double& x, double& y)
{
double tmp = x;
x = y;
y = tmp;
}
void Swap(char& x, char& y)
{
char tmp = x;
x = y;
y = tmp;
}
2. 泛型编程概念
- 编写的代码与数据类型无关,任何数据类型都能使用编写的功能称为泛型编程。
- 泛型编程是代码复用的一种手段,模板是泛型编程的基础。
🌈 Ⅱ 函数模板
1. 函数模板概念
- 一个函数模板代表了一个单独的功能,一个函数模板就能够对某一个功能所有类型的数据实现。
- 函数模板与参数的类型无关,只有在被使用时会进行参数化,根据实参的类型来完成函数的特化类型版本。
2. 函数模板格式
1. 函数模板格式
- template:用来定义模板的关键字。
- typename:用来定义模板参数的关键字。
template<typename T1, typename T2, ... , typename Tn>
返回值类型 函数名(参数列表)
{
函数体
}
2. 函数模板示例
template<typename T> // T 可以表示任何数据类型
void Swap(T& x, T& y) // 根据万用类型 T 创建函数模板
{
T tmp = x;
x = y;
y = tmp;
}
3. 函数模板原理
- 在上述示例中,Swap 函数压根就不存在。
- 交换 int 型的和交换 char 型的调用的并不是同一个函数。
- 函数模板只是一个模板,本身不是函数,而是编译器在知道了你要交换什么类型的数据,然后根据实参类型利用函数模板现场生成了一个交换具体类型的函数。
- 如果在已经有了现成的具体函数,编译器会调用现成的函数。
- 前提是现成的函数要够好用,如果实参是 double ,现成函数的形参却是 int ,编译器还是会自己根据模板推演出一份 double 类型的函数。
- 编译器根据 实参类型 + 函数模板 自动生成函数称为函数模板隐式实例化。
4. 函数模板显式实例化
- 隐式实例化:编译器根据实参和模板自动生成函数。
- 显式实例化:指定模板参数的类型,并且强制调用模板。
- 格式:函数名<指定模板参数类型>(实参);
Swap<double>(d1, d2); // 指定模板参数为 double,并且编译器必须使用模板