泛型编程
我们之前写swap(交换两个变量),不同类型的是不是得重复写一个函数名相同、参数不同的函数【函数重载】
可是像这种泛型编程,有两种弊端
①代码复用率低
②代码维护性低
那有没有只写一个函数就能解决不同参数实现函数swap(交换)呢?
函数模板
函数模板概念
函数模板是一种代码复用机制,它允许编写与数据类型无关的函数定义,使得同一个函数可以处理多种不同类型的参数。
简而言之,函数模板提供了类型参数化的能力。
函数模板格式
一般推荐使用关键词class
在主函数中,两个函数名一样,调用这两个函数的地址相同吗?
根据反汇编的可以看到,它们的地址是不一样的
函数模板的原理
函数模板的实例化
隐式实例化
当函数模板被调用时,编译器会根据传递给模板的参数类型自动生成函数的特定版本。
这个过程称为隐式实例化。
编译器会在需要的时候自动创建一个特定类型的函数版本
显式实例化
显式实例化是指程序员明确告诉编译器为特定的类型创建模板函数的实例。
显式实例化通常用于模板代码的分离编译,或者当编译器无法自动推导模板参数时。
接上面代码,我想把变量b转换为double怎么转?
有两种方式
看看下面这个函数显式实例化的方式
模板参数的匹配原则
当一个非模板函数与一个函数模板具有相同的名字和相同的调用形式时,非模板函数将优先于模板函数被调用。
如果需要调用模板函数,则可以通过显式实例化来实现。
模板实例化与非模板函数可以构成重载关系
类模板
类模板的定义格式
template <typename T> class ClassName { // 类成员声明 public: ClassName() { /* 构造函数代码 */ } ~ClassName() { /* 析构函数代码 */ } // 其他成员函数和数据成员 void memberFunction(T param) { // 使用类型T的函数实现 } T dataMember; // 使用类型T的数据成员 // ... };
那支持多个参数不同的类型该怎么定义?
template <typename T1, typename T2, ...> class ClassName { // 类成员声明 public: // ... };
类模板的实例化
解释:
Stack构造函数传有参数 ,创建对象时要提供参数