泛型编程
比方说现在要去实现一个通用的交换函数,以我们现在的思路,肯定是通过函数重载去解决。但是这样子的话有几个缺点:重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函数;代码的可维护性比较低,一个出错可能所有的重载均出错。
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,typename关键字,模板参数T
函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本 。 这个模板参数可以具体充当指针类型与自定义类型等 typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class)
函数模板的原理
函数模板是一个蓝图,它本身并不是函数 ,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器 在编译器编译阶段 ,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用 。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此。
函数模板的实例化(隐式)
用不同类型的参数使用函数模板时,称为函数模板的实例化 。模板参数实例化分为:隐式实例化和显式实例化。 隐式实例化就是让编译器根据实参推演模板参数的实际类型 简单例子:
# include <iostream>
# include <stdlib.h>
using namespace std;
template < typename T >
void Swap ( T& x, T& y)
{
T tmp = x;
x = y;
y = tmp;
}
template < typename T >
T add ( T x, T y)
{
return x + y;
}
int main ( )
{
int a = 10 ;
int b = 20 ;
Swap ( a, b) ;
cout << a << " " << b << endl;
float c = 1.234 ;
float d = 9.3424 ;
cout << add ( a, b) << endl;
cout << add ( c, d) << endl;
return 0 ;
}