引言
假设我们有一个swap函数能够交换两个int值,此时需要交换两个double值。有一种方式是去复制swap函数的代码,并用double替换所有的int。这种修改方式不仅会产生相似代码,而且不便于后期的维护。我们知道,在完成交换double值的修改后,随时可能会再来个交换char值的需求。
C++为我们提供了函数模板,可以通过将类型作为参数传递给模板,不用复制代码便可以产生该类型的函数,大大提高了代码的可复用性和延展性。
函数模板格式
template 是模板关键字,class/typename 是声明类型 T 和 U 的关键字 ,T 和 U 是模板形参,<>中模板形参可以是C++内置类型或者用户自定义类型,且不可为空。 function_declaration 则是函数声明。
函数模板示例
支持交换int double char值的swap函数模板:
#include <iostream>
using namespace std;
template < typename T >
void swap_usr(T& x, T& y){
T temp = x;
x = y;
y = temp;
}
int main(){
int a = 10;
int b = 100;
double x = 3.14;
double y = 6.66;
char i = '$';
char j = '@';
cout << "a b x y i j before swap" << endl;
cout << "a:"<< a << " b:"<< b << endl;
cout << "x:" << x << " y:" << y <<endl;
cout << "i:" << i << " j:" << j <<endl;
swap_usr(a, b);
swap_usr(x, y);
swap_usr(i, j);
cout << "a b x y after swap" << endl;
cout << "a:"<< a << " b:"<< b << endl;
cout << "x:" << x << " y:" << y <<endl;
cout << "i:" << i << " j:" << j <<endl;
return 0;
}
运行结果:
before swap
a:10 b:100
x:3.14 y:6.66
i:$ j:@
after swap
a:100 b:10
x:6.66 y:3.14
i:@ j:$
上述程序中函数模板自动完成了隐式重载函数,我们在调用 swap_usr(a, b) 时,实际在调用 swap_usr<int>(a, b)。同理swap_usr(x, y) 为 swap_usr<double>(x, y)。当然我们可以在程序中显式调用函数模板,需要再调用时在<>传入制定类型。
模板函数时类型安全的。如果我们把 int 和 double 类型的参数同时传入函数模板 swap_usr(x, a) ,那么在编译的时候会报错:
note: candidate template ignored: deduced conflicting types for parameter 'T' ('double' vs. 'int')
可以看出,模板不再支持编译器的自动类型转化,因为我们在定义模板函数swap_usr(T& x, T& y) 时指定了 x 和 y 为同一种类型。
除了作为函数的参数类型之外,<class T> 中的 T 还可以作为返回类型,而且可以有多个参数类型。
template <class T>
T GetMax (T a, T b) {
T result;
result = (a>b)? a : b;
return (result);
}
关于函数模板,先记这么多吧。后边还有重头戏——类模板。