模板机制是用来定义数据类型不同但逻辑结构相同的数据对象的通用行为。在模板中,运算对象的类型不是实际的数据类型,而是一种参数化的类型。
模板分为函模板和类模板,带参数类型的函数称为函数模板,带参数类型的类称为类模板
函数模板
函数模板并不是一个函数,它相当于一个模子,定义一次即可使用不同类型的参数来调用该函数模板。来减少代码的书写。
我们先来看函数模板的定义,如果定义一个实现两个数相加的函数add(),要实现int、double、float等多种类型的数据相加,这要定义很多个函数如:
int add(int a,int b){
}
double add(double a,double b){
}
float add(float a,float b){
}
……
这时,为了简便我们就可以运用函数模板,其语法格式如下:
template<tempname 类型占位符>
返回值类型 函数名(参数列表)
{
//函数体;
}
template是声明模板的关键字,<>中的参数称为模板参数,tempname关键字用于标识模板参数可以用class关键字代替。模板参数不能为空,一个函数模板中可以有多个模板参数。template下面是定义的函数模板,函数模板定义方式与普通函数定义方式相同,只是参数列表中的数据类型,要使用<>中的参数名表示。
下面演示一下函数模板的用法:
#include<iostream>
using namespace std;
template<tempname T> //定义函数模板
T add(T t0,T t1)
{
return t0+t1;
}
int main()
{
cout<<add(1,2)<<endl;
cout<<add(1.5,2.7)<<endl;
return 0;
}
运行结果为:
3
4.2
接着我们来看函数模板的实例化
编译器生成具体类型函数的过程就叫做实例化。
1、隐式实例化
隐式实例化是根据函数调用时传入的参数的数据类型确定模板参数T的类型,模板参数的类型是隐式确定的。上述演示中第一次调用add()函数模板时传入的int类型1和2,编译器根据传入的实参推演出模板参数类型是int,就会根据函数模板实例化出一个int类型的函数,如下,
int add(int t0,int t1)
{
return t0+t1;
}
2、显式实例化
隐式实例化不能为同一个模板参数指定两种不同的类型,如add(2.1,2)函数参数类型不一致,编译器就会报错。显式实例化就可以解决手机类型不一样的问题
语法格式如下:
template 函数返回值类型 函数名<实例化的类型>(参数列表);
<>中是显式实例化的数据类型,如果显示实例化为int类型,则在调用时,不是int类型的数据会转换为int类型再进行计算。如将上述演示中的add()函数模板显式实例化为int类型,代码如下:
template int add<int>(int t0,int t1);
下面演示函数模板显式实例化的用法:
#include<iostream>
using namespace std;
template<tempname T>
T add(T t0,T t1)
{
return t0+t1;
}
template int add<int>(int t0,int t1);
int main()
{
cout<<add(5,2.5)<<endl;
cout<<add(1.5,2.7)<<endl;
return 0;
}
运行结果为:
7
4.2
类模板见下一篇