C++提供模板技术,以实现泛型编程,提高代码的复用性。
1. 基本语法
template <typename T>
这里定义了一个模板,名字叫T,告诉编译器后面的代码中的T不要报错,它是一个通用数据类型
下面看一个实例,我们写一个交换两个数的函数:
template<typename T>
void Swap(T& a, T& b) {
T temp;
temp = a;
a = b;
b = temp;
}
这里的T是通用数据类型,可以是float,int,double之类的类型。如何确定使用类型呢?有两种方法 :
1.自动类型推导(直接传参,编译器通过自行判断参数类型以确定T的类型,但应该推导出一致的数据类型T)
2.显示指定类型
Swap(a,b); // 1.
Swap<int>(a,b); // 2.
2. 普通函数与函数模板的区别
- 普通函数调用时,可以发生隐式类型转换(比如char–>int,int–>double)
- 函数模板在使用自动类型推导时,不可以发生隐式类型转换
- 函数模板在使用显示指定类型时,可以发生隐式类型转换
3. 普通函数和函数模板的调用顺序
普通函数和函数模板是可以有相同函数名称的,也就是说可以发生重载,他们的调用规则如下:
- 如果函数模板和普通函数都可以实现,优先调用普通函数
- 可以通过空模板参数列表来强制调用函数模板
Swap<>(a,b);
- 函数模板也可以重载
- 如果函数模板可以产生更好的匹配,优先调用函数模板(适用性更高)
4. 具体化函数模板
比如说,我们需要判断两个类的实例化对象中的一个变量a的值是否相同,情景如下:
class person{
public:
int a;
};
person p1; p1.a = 1;
person p2; p2.a = 2;
如果直接使用 p1 == p2来判断是不行的,因为没有实现 == 的重载,这个时候可以采用具体化函数模板来实现,语法如下:
template<> bool Compare(person& p1, person& p2){
return p1.a == p2.a;
}
实现这个具体化操作的前提,是我们已经有一个函数模板:
template<typename T>
bool Compare(T& a, T& b) {
return a == b;
}
以后,只要我们传入模板函数的参数类型是person,统一由第1个函数进行对比,那么如果传入的是普通的数,那么就有第2个函数模板进行对比。