在开始介绍函数模板之前,我们先来说一说为什么要用函数模板,有什么好处。从上篇文章函数重载,我们可以看到,我们写一个max函数,输入三个数字,然后返回最大值,很自然地,两个参数的类型和返回的类型必须是相同的。如果不使用模板,我们需要使用函数重载,为不同的类型写不同的函数;就像在函数重载第一个例子中,我们接连写了三个max函数,分别用于整型、浮点型和长整型数据,很是麻烦;但如果用上模板的话,可以大大减少代码量:
int max(int a, int b, int c) //函数定义 求三个整数中最大者;
{
if(b>a) a=b;
if(c>a) a=c;
return a;
}
float max(float a, float b, float c) /函数定义 求三个浮点数中最大者;
{
if(b>a) a=b;
if(c>a) a=c;
return a;
}
这里我只写了2个函数,实际上short, long, unsigned, double等等类型都需要专门的max函数,结果就是需要写十几个几乎一摸一样的代码。如果函数功能更复杂一些,函数实现需要更多行,就会出现大量冗余重复的代码,而且不容易维护,很容易出错。这个时候如果我们能够根据特定的模板批量生成一系列代码,将会方便很多。为此,我们可以使用C++中的模板;
那么什么是函数模板呢?
模板就是编译器生成代码用的模子。模板有两类,函数模板和类模板。如果想要生成函数代码,则需要用函数模板,如果想要生成类定义,则需要用到类模板。我们这里就只介绍函数模板。
我们可以为上面的一系列max函数写一个函数模板:
template<typename T>
T max(T a,T b,T c)
{
if(b>a) a=b;
if(c>a) a=c;
return a;
}
先不说语法的问题,大致的样子和原函数是很像的哈,好了,我们已经定义了一个函数模板,那么怎么去生成函数代码?事实上我们不需要做额外的事情,如果我们使用了max函数,编译器就会自动帮我们生成对应类型的代码。函数模板的使用方式很简单,只需要在模板的名字后面写一对尖括号,尖括号内写上实参列表就可以使用了。
double d = max<double>(1.2, 2.4,3.6);
编译器看到这一行,就会自动帮我们生成double版本的max函数,生成出来的函数等价于把函数模板中的所有T都替换成double。在这里max可以看做是double版本的max函数的函数。
函数模板的优点:
我们可以从上面的例子中看出,用函数模板更方便简洁,不需要重复写类似的重载函数。除此外,因为函数代码是在使用的时候生成出来的,所以如果我们没有使用这个函数,编译器就不会生成这个代码,这样我们可以减小程序的大小。例如,我们使用了max,但是没有使用max,那么程序中只有max函数,不会有max函数。