c++中的模板(Template),是一种参数化类型机制,模板是C++泛型编程中不可缺少的一部分,是实现代码重用机制的一种工具,它可以实现类型参数化,即把类型定义为参数,使程序摆脱对于类型的依赖,从而实现了真正的代码可重用性。模板分为函数模板和类模板。本文我们先介绍函数模板。
在没有学习模板时,我们求两数之和(或者两数比较时compare)时,如果要写不同类型的两数相加时,通常要写很多个函数它们的返回值、参数类型各不相同如下所示,这样往往导致代码过于冗余。
int Sum<int>(int a,int b)
{
return a + b;
}
double Sum<double>(double a, double b)
{
return a + b;
}
char Sum<char>(char a, char b)
{
return a + b;
}
而使用了模板后,这个问题就得以解决。
1.函数模板的定义、实例化:
类模板和函数模板都是以 template 开头,后跟<typename 模板类型参数名>类型参数不能为空,多个类型参数名之间用逗号隔开。定义模板类型参数时,typename与class作用相同。
声明函数模板的语法为:(以求两数之和Sum为例)
template<typename T>
T Sum(T a, T b)
{
return a + b;
}
int main()
{
Sum(10,20);//可调用成功,模板的实参推演
Sum<int>(10,20);//实例化模板类型参数为int
Sum<double>(10.2,15.8);//实例化模板类型参数为double
return 0;
}
注意:第一行模板头后面不加分号。
模板实例化时,如上述第9行代码,先看是否已经存在实例化为int类型的模板函数,若存在,则直接调用,若不存在,再进行实例化,即类型参数完全相同的模板实例化仅存在一份。
上述代码第9行,模板实例化过程,实例化模板类型参数为int,其实是一个类型重定义的过程,模板实例化过程生成的代码叫模板函数,如下所示:
int Sum<int>(int a, int b)
{
return a + b;
}
这样,我们就把需要写很多个求两数之和的代码,通过函数模板的方法大大的压缩了,并且以后若想在增加求某种类型的两数之和时只需要在主函数中增加一行代码如下就行了
Sum<float>(10.1,10.5);
通过上述举例应用,我们知道,所谓函数模板,实际上是建立一个通用函数,它所用到的数据的类型(包括返回值类型、形参类型、局部变量类型)可以不具体指定,而是用一个虚拟的类型来代替(实际上是用一个标识符来占位),等发生函数调用时再根据传入的实参来逆推出真正的类型。这个通用函数就称为函数模板。
在函数模板中,数据的值和类型都被参数化了,发生函数调用时编译器会根据传入的实参来推演形参的值和类型。换个角度说,函数模板除了支持值的参数化,还支持类型的参数化。一但定义了函数模板,就可以将类型参数用于函数定义和函数声明了。说得直白一点,原来使用 int、float、char 等内置类型的地方,都可以用类型参数来代替。
template <class T>
void fun(T a)
{}
int main()
{
int a=0;
const int b=0;
fun(a);
fun(b);
fun(&a);
fun(&b);
}
上述代码,模板的实参推演在编译过程中进行,上述代码,生产了三个模板函数:
typedef int T
void fun<int>(T a)//fun(a)与fun(b)生成的模板函数一样,仅存一份
{}
typedef int* T
void fun<int*>(T a