》模板的引入,为什么要使用模板?

在程序设计中往往存在这样一种现象:两个或多个函数的函数体完全相同,差别仅在于他们的参数类型不同,就需要分别给不同的数据类型定义不同的版本。

解决以上问题的一个比较好的方法就是使用模板。模板是实现代码重用机制的一种工具,他可以实现类型参数化,即把类型定义为参数,从而实现代码复用。

》模板的分类:

模板分为函数模板和类模板。他们分别允许用户构造模板函数和模板类。

》函数模板:

建立一个通用函数,其函数返回类型和形参类型不确定,用一个虚拟的类型来代表,这个通用函数就称为函数模板。

函数模板声明格式:

template <typename 类型参数>

返回类型 函数名(模板形参表)

{函数体

}

其中template是一个表明声明一个模板的关键字;

typename也可以用class作用一样表示其后是一个虚拟的类型名;

类型参数实际上是一个类型名;

例:

template<typenameT>Tmax(Tx,Ty){return(x>y)?x:y;}


》如何使用函数模板

上面max()函数代表一类函数,要使用这个模板函数就需要将T实例化为确定的数据类型,这个实例化的参数就叫做模板实参。

函数名(模板实参表)

例:

template<typenameT>Tmax(Tx,Ty){return(x>y)?x:y;}intmain(){inti1=19,i2=23;doubled1=50.344,d2=4656.346;charc1='k',c2='n';cout<<"Themaxofi1,i2is="<<max(i1,i2)<<endl;cout<<"Themaxofd1,d2is="<<max(d1,d2)<<endl;cout<<"Themaxofc1,c2is="<<max(c1,c2)<<endl;return0;}

结果:


从上例看出,函数模板提供了一类函数的抽象,它以类型参数T为参数及函数返回值的虚拟类型。函数模板经实例化而生成的具体函数称为模板函数。


》一个和指针相关的函数模板

template<typenameAT>ATsum(AT*array,intsize=0){ATtotal=0;for(inti=0;i<size;i++){total+=array[i];}returntotal;};intint_array[]={11,22,33,44,55,66,77,88,99,1010};doubledouble_array[]={11.1,22.2,33.3,44.4,55.5,66.6,77.7,88.8,99.9,100.10};intmain(){intitotal=sum(int_array,10);doubledtotal=sum(double_array,10);cout<<"这个整型数组的元素之和是:"<<itotal<<endl;cout<<"这个双精度型数组的元素之和是:"<<dtotal<<endl;return0;}

结果:

在程序中生成了两个模板函数,sum(int_array)和sum(double_array)分别将类型参数实例化为int型和double型。


》同样的函数模板也允许使用多个类型参数,但是template定义部分的每个类型参数前必须要有关键字typename。

template<typenamepara1,typenamepara2>voidtwo_para(para1x,para2y){cout<<x<<''<<y<<endl;}intmain(){two_para(99,"zhang");two_para(123.45,888L);return0;}

结果:

1.在这个程序中,生成了两个模板函数,“two_para(99,"zhang")”,分别用模板实参int,char*将类型参数para1和para2实例化,“two_para(123.45,888L)”,分别用模板实参double,long将类型参数para1和para2实例化,

2.在template语句与函数模板定义语句之前不允许插入别的语句。

3.同一般函数一样,函数模板也可以重载。


template<typenameType>Typemin(Typex,Typey){return(x<y)?x:y;}template<typenameType>Typemin(Typex,Typey,Typez){Typet;t=(x<y)?x:y;return(t<z)?t:z;}intmain(){intm=10,n=20,min2;doublea=10.1,b=20.2,c=30.3,min3;min2=min(m,n);min3=min(a,b,c);cout<<"min("<<m<<","<<n<<")="<<min2<<endl;cout<<"min("<<a<<","<<b<<","<<c<<")="<<min3<<endl;return0;}

结果:


》函数模板和非函数模板可以重载,调用顺序是:首先寻找一个参数完全匹配的非函数模板,如果找到就调用它,如果没有就寻找函数模板将其实例化,产生一个匹配的模板函数。