说明:
函数模板的应用场景:通常,编程过程需要用到同一个函数应用于参数不同类型或参数不同数量的情况,虽然函数重载可以解决以上两种情况,但是面对函数体内函数语句一样的情况时就会显得繁琐,函数模板便是在重载函数上对函数体内重复语句的优化,实现重载函数的合并,减少作业量。(注:函数模板也有其限制,例针对两个变量的交换函数应用在数组交换时便行不同,或者是参数数量不同时,下面会讲到)
正文:
函数模板的相关内容:
1 函数模板的通用形式(以Swap函数为例):
含有template关键字,且必须为<>; 类型可为typename 或者 class,一般使用的是typename,类型名可以简洁写为T;
此语句下面即跟着要作为模板的函数;
2 函数模板的实例化(显式与隐式):
根据函数模板参数类型可由开发环境自动识别从而调用相应的函数的特性,在编译期时,不对函数进行语法检查,故无法识别函数体内语句是否符合相应语法。也可以说此时并不存在该函数(也就无法知道函数内到底有什么样的语句以及是否符合语法)
隐式:
只有在调用该函数的时候,才会根据实参类型进行相应函数的生成,从而完成函数的实例化。
显示:
形式 template void Swap<int >(int , int ); 语法规则:在声明前加template关键字,且函数名后加<>指示类型,当编译期看到此声明时,就会实例化一个你所指示的类型的一个函数(注意区分函数模板的具体化的语法规则)。
3 函数模板的重载:
当参数列表的参数数量不同但要使用相同函数名时,称为函数重载,同样适用于函数模板的重载。
template<typename T>
void Swap(T a[],T b[],int len)
数组交换就可以用上示模板(小点:不是所有的模板参数必须使用模板参数类型,此时的len就是非模板参数类型,且此时的len参数必须为常量,即不可为变量以及常变量)
4 函数模板的特例化(也称为具体化):
当参数列表的参数数量相同但要求的算法不同时,就要使用到特例化函数;
其形式为:
template<>void Swap<char *>(char * a,char * b) 即当参数类型为char * 时优先使用此函数。 Swap后尖括号类型可省略为Swap(char *a,char *b),因其只是一个强调或标示。
也就是说 template<>Swap(char *,char *)与template<>Swap<char *>(char *,char *)等价
补充:
关于各类型函数使用优先级:最优先使用非模板函数,再者特例化函数,最后模板函数(显式实例化优先)。具体规则可参考C++ primer Plus 第六版 一 书的函数模板部分
本博客参考:C++ primer Plus 第六版