前面跟大家介绍了一下函数模板的使用,其实所谓的函数模板就是函数体相同的代码片段的合集,通过显性或者隐性的方式即可使用函数模板生成相应的实际函数体,终编译运行。

这样在一定程度上增加了代码片段的高度整合和可复用性。

那么函数模板其实跟普通的函数并没有本质上的区别,而函数重载是C++中的重要属性,当出现了同名的函数模板与普通函数之间同样也会发生函数重载。

值得注意的是 : 重载(overload)是一个静态的匹配过程,在编译器即可确定;而重写override会使用到虚函数,是一个动态的处理过程,父类指针根据参数对象类型来选择具体实现,这两个概念记得区分一下。

02

重载规则

其实所谓的重载就是根据参数的差异实现的一种佳匹配,似乎也没有什么特别的,即哪一种方法能够更加接近调用的形式就会优先匹配,如果编译器无法抉择就只能够报错,存在二义性了。
下面以一个例子说明一下函数模板与普通函数重载的一些规则。
 1#include<cstdio>
2#include<iostream>
3using namespace std;
4
5//函数模板
6template<typename Ty>
7Ty Add(Ty param1,Ty param2)
8{
9    cout<<"***TemplateFunction***"<<endl;
10    return param1 + param2;
11}
12
13//普通函数
14float Add(float param1,float param2)
15{
16    cout<<"***NormalFunction***"<<endl;
17    returnparam1 + param2;
18}
19
20int main(void)
21{
22
23    float a = 2.2;
24    float b = 3.3;
25
26    cout<<"Addresult :"<<Add(2.2,3.3)<<endl<<endl;        
27
28    cout<<"Addresult :"<<Add(2.2f,3.3f)<<endl<<endl;      
29
30    cout<<"Addresult :"<<Add(a,b)<<endl<<endl;      
31
32    cout<<"Addresult :"<<Add(1,3)<<endl<<endl;      
33
34    cout<<"Addresult :"<<Add(2,3.3)<<endl<<endl;   
35
36    cout<<"helloC++"<<endl;
37
38    return1; 
39
40}
1、很多初学者会拿着个输出来做实验,而对于浮点类型,普通函数与模板函数都是可以正确匹配的,而终输出的结果函数模板匹配成功,可能会得出当普通函数与模板函数都可以正确匹配时优先匹配模板函数的错误结论
然而你采用第二个输出就发现结论不准确,其原因在于直接传入的浮点数值类型是双精度的,如果采用普通函数需要将doule转为float,而模板函数能够直接匹配doule类型,所有模板此时为佳匹配。
当在数值常量后指明f - float类型,则函数模板与普通函数都是可以正确匹配的,此时,输出结果显示匹配的普通函数类型,所以函数重载会优先匹配普通函数类型,毕竟普通函数类型更加的明确。
2、自动强制类型转换在编程中也是经常发生,不过建议大家不管在C语言还是C++编程中都好采用显示的强制转换,代码上也更加的清晰。前面介绍函数模板的时候,小哥跟大家也提过,函数模板是不支持强制类型转换的,其实也很好理解,原本函数模板就是一种类型参数化的形式,它不知道该强制转化为什么类型。所以如果要用到强制类型转化只能是显式指明或者利用普通函数。
因此当需要隐式转化才能匹配普通函数时,如果此时函数模板能够正常匹配,必定是优先匹配模板函数,比如第4个输出,参数需要强制类型转化为float类型才能匹配普通函数,而函数模板直接可以匹配,优先会匹配函数模板。
而当函数模板也无法匹配,就只能通过强制类型转化以后匹配普通函数,这也就是第5个输出的结果。

  后 


这里小哥就介绍了一下C++中函数模板与普通函数的重载问题,希望本文能够对你有帮助,该系列还会持续更新,大家可以持续关注~

文章来源:嵌入式情报局

相关文章