一.函数模板
1.函数模板的概念
函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器
在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应的函数以供调用。比如:当用double来行使用函数模板时,编译器通过堆实参的类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此。
例如:
注意:其中 Add(a,d)与Add(c,d) 调用的不是同一个函数;
模板参数类似于函数参数,函数参数定义的是形参对象,模板参数定义的是类型;
函数模板不能自动的发生类型转换,但普通函数就可以;
2.函数模板的匹配原则
1.一个非模板函数可以和一个同名的模板函数同时存在,并且这个函数模板可以被实例化为这个函数;
如:
2.对于非模板函数和同名的模板函数同时存在时,如果其他条件相同的情况下,会优先调用非模板函数而不会通过模板实例化,如果模板可以生成一个更好的,更匹配的,则会通过模板实例化;
如:
3.函数模板的实例化
例如:
当我们需要计算两个不同类型的数据求和时:
这种情况,参数既有int也有double,编译器就不知道该生成一个int的函数还是double的函数,这个时候就需要我们自己显示实例化;
函数模板的实例化分为显示实例化和隐式实例化;
1.显示实例化
显式实例化:在函数名后加< >里面指定实例化类型;
2.隐式实例化
隐式实例化:如果没有显示实例化,则让编译器通过实参类型类推演模板参数的类型
注意:
当函数参数没有模板参数时,模板函数必须显示实例化
二.类模板
1.类模板的定义
类模板的定义格式:
template<class T1,class T2,class T3…… >
有了类模板,可以解决在一个文件中用不同类型的栈,如一个文件中需要使用int类型的栈,还需要其他类型的栈,如果没有类模板,就只能使用一个类型的栈;
注意:
类模板只能显示实例化;
对于普通类:类名就是类型
类模板实例化的类,类名不是类型,类名<数据类型>才是类型;
其中,构造函数名是类名,不是类型