模板并不是一个实实在在的类或函数,仅仅是一个类或函数的描述。
模板使类或函数可在编译时定义所需处理和返回的数据类型,有利于代码的重用。
函数返回值类型可以返回除了函数和数组以及类之外的任意类型。
1、函数模板
1.1、定义一个函数模板
函数模板并不是一个可以直接使用的函数,它时可以产生多个函数的模板,即一个函数可以适应不同数据类型。定义如下:
1 2 3 4 5
| template<typename/class 形参名,typename/class 形参名......> 返回值类型 函数名(参数列表) { 函数体; }
|
其中,template是声明模板的关键字,typename和class是定义形参的关键字,这里typenam和class没有区别。<>的参数称为模板形参,模板形参和函数形参很像,但模板形参不能为空。
template下面就是定义的一个函数模板,它与普通的函数定义方式相同,只是参数列表中的数据类型要使用<>中的形参名。
1.2、函数模板的实例化
函数模板并不是一个函数,它只相当于一个模子,定义一次即可使用不同类型的参数来调用该函数,即可以提高代码的复用性。但使用函数模板并不会减少最终可执行程序的大小,因为在调用函数模板时,编译器会根据调用时的参数类型进行相应的实例化。而实例化就说用类型参数去替换模板中的模板参数,生成一个具体类型的真正函数。
1.2.1、隐式实例化
隐式实例化时根据函数调用时传入的数据类型确定模板形参T的类型,模板形参的类型是隐式确定的。例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #include<iostream> using namespace std; template<typename T> T add(T t1,T t2) { return t1+t2; } int main(void) { cout<<add(1,2)<<endl; cout<<add(1.2,2,4)<<endl; system("pause"); return 0; }
|
如上所示,当第一次调用add()函数模板时,传入的是int型数据add(1,2),此时编译器根据传入的实参推演出模板形参类型是int,就会将函数模板实例化出一个int类型的函数,如下图: