千家信息网

C++之如何彻底理清重载函数匹配

发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,小编给大家分享一下C++之如何彻底理清重载函数匹配,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!匹配过程为便于说明,将函数
千家信息网最后更新 2025年11月07日C++之如何彻底理清重载函数匹配

小编给大家分享一下C++之如何彻底理清重载函数匹配,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

匹配过程

为便于说明,将函数匹配分为三个阶段,确定候选函数,确定可行函数,确定最佳匹配函数。

确定候选函数

候选函数也就是和被调用的函数同名,并且其声明在调用点可见。举个简单的例子。

假设有两个文件,1.cpp和2.cpp,内容分别如下:

1.cpp:

//函数1 void f(int a,short b) { cout<<"func0"<

2.cpp:

#include using namespace std; //函数2 void f(int a,double b) { cout<<"func1"<

在这里,候选函数其实只有两个,其中第一个函数在其调用点不可见,而第四个函数和被调用的函数不同名,因此这两个都不是候选函数。

确定可行函数

可行函数指的是本次调用传入的实参能够被候选函数使用。它要满足两个条件, 一是形参数量和实参数量相同,二是每个实参的类型和对应形参类型相同或者能够转换成形参的类型。

还是前面的例子,实参的个数和类型与第二个函数完全匹配,而在经过算术转换之后,也能够与第三个函数匹配。

确定最佳匹配函数

最佳匹配的函数是最终调用的。最佳匹配最基本的思想是认为,实参类型越接近,它们就越匹配。还是前面的例子,实参要与第三个函数匹配,需要进行算术转换,而与第二个函数完全匹配,因此第二个函数是最佳匹配函数。最终的运行结果如下:

func1

最佳匹配原则

一般来说,精确匹配肯定比需要类型转换的匹配要更好,但是当形参有多个,并且无法完全精确匹配的时候,要确定最佳匹配函数就有点困难了。

但是有下面的原则:

  • 函数的每个实参的匹配都不能比其他可行函数更差

  • 函数至少有一个实参的匹配要比其他可行函数更好

那么问题又来了,什么是更好,什么又是更差呢?编译器将实参类型到形参类型的转换划分了等级:

1.精确匹配,包括实参类型和形参类型相同,实参从数组或函数转换成对应的指针类型,向实参添加顶层const或从实参删除顶层const

2.通过const转换实现的匹配

3.通过类型提升实现的匹配

4.通过算数类型转换实现的匹配

5.通过类类型转换实现的匹配

等级越前,匹配也就越好。接下来对上面的内容做一些解释。

精确匹配

精确匹配比较容易理解。关于顶层const问题,可以参考《函数重载》

通过const转换实现的匹配

所谓通过const转换实现的匹配,指的是通过加const限定词,能够与可行函数精确匹配。例如:

#include using namespace std;//函数1/*int f(string &a){ cout<<"call function 1"<

在这里,test可以通过const转换,从而匹配函数2,将能够找到最佳匹配函数2(当前情况它也只有一个可选了)。
运行结果如下:

call function 2

如果把函数1的注释去掉再运行,就会发现,虽然第一个调用既能匹配函数1,也能匹配函数2,但是由于匹配函数2的时候,需要const转换,因此比精确匹配要差,最终,它会调用函数1。
去掉函数1的注释后,运行结果如下:

call function 1

通过类型提升实现的匹配

关于类型提升,这里不多做介绍。简单说明类型提升规则:

  • float将提升到double

  • char、short和相应的signed、unsigned类型将提升到int

我们来看一个示例:

#include using namespace std;//函数1/*int f(short a){ cout<<"call function 1"<

同样地,我们暂时把函数1注释掉。由于a是short类型,但是通过类型提升,可以转换为int,因为它也能调用函数2。运行结果如下:

call function 2

但去掉函数1注释后,由于精确匹配优于通过类型提升的匹配,因此将会调用函数1,运行结果如下:

call function 1

通过算术类型转换实现的匹配

short int和float,double等之间的转换,都是算术类型之间的转换。我们仍然来看一个例子:

#include using namespace std;//函数1int f(int a){ cout<<"call function 1"<

在这里,short类型的a既可以通过类型提升转换为int,也可以通过算术类型转换成为double。这个时候,哪个才是最佳匹配呢?我们看运行结果:

call function 1

对于这个结果,并不意外,因为前面我们已经说到,通过类型提升的转换是优于算术转换的,因而函数1是它的最佳匹配函数。

通过类类型转换实现的匹配

这里不多做介绍。我们也很容易理解。诸如父类和子类之间的转换都是如此。

二义性示例

前面基本能够找到最佳匹配,我们来看一个有多个可行函数,最后却没有最佳匹配的情况。

#includeusing namespace std;//函数1void f(double a,int b){ cout<<"function 1"<

函数1和函数2都是可行函数,但它们都没有在任意一个参数上比对方更好,因此将会产生二义性,编译时将会报错:

error: call of overloaded 'f(int, int)' is ambiguous

总结

  • 调用重载函数时,应当避免强制类型转换。

  • 设计重载函数时应避免可能产生的二义性。

  • 如果无法找到可行函数,编译器将报错。

  • 设计重载函数的时候,希望避免需要用到上面的知识,而在定位问题时能够利用上面的知识很快定位问题。

以上是"C++之如何彻底理清重载函数匹配"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

函数 类型 可行 精确 结果 运行 算术 形参 两个 例子 内容 时候 注释 问题 面的 相同 三个 之间 二义性 可以通过 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 我的世界服务器矿洞在哪 昌平区网络软件开发大概费用 c语言小软件开发流程图 万德数据库和终端太贵了 网络安全教育手抄报截图 英雄之路是哪个服务器 群晖的服务器安全吗 ac管理服务器怎样收费 公共基础设施网络安全 网络安全竞赛小品的短的梗概 导致危害网络安全后果法定条件 世界智能科技与网络安全 路由器创建vpn服务器 南京软件开发工作好找吗 数据库中触发器重要么 服务器配置需求文档 新洲环境好的计算机软件开发 大学生网络安全发声亮剑 北京环宇同创网络技术 成都泽腾网络技术怎么样 5.2使用数据库教学反思 幼儿园参加网络安全教育 怎样注册泰拉瑞亚服务器 重庆街道党性体检软件开发 山东联通软件开发工程师面试问 金仓数据库初始化失败 软件开发转美工 太原2u服务器价格 电子表格快捷复制数据库 地区分行有网络安全部门吗
0