🫒函数重载和匹配
2022-5-10
| 2023-8-2
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property
 

 

函数重载

函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表的函数,这组函数被称为重载函数,main函数不能重载。
这些函数接受的形参类型不一样, 但是执行的操作类似。调用这些函数时, 编译器根据传递的实参类型推断想要的是哪个函数:
函数的名字仅仅是让编译器知道它调用的是哪个函数,函数重载可在一定程度上减轻起名字的负担。
 
对于重载的函数来说,它们应该在形参数量或形参类型上有所不同。不允许两个函数除了返回类型外其他所有的要素都相同(只有返回类型不同,调用函数的时候不能区分调用的是哪一个函数):
 

重载和const形参

顶层const不影响传入函数的对象,一个拥有顶层const的形参无法和另一个没有顶层 const 的形参区分开来。
 
如果形参是某种类型的指针或引用,则通过区分其指向的对象是常量还是非常量可以实现函数重载,此时的const是底层的。
当传递给重载函数一个非常量对象或者指向非常量对象的指针时,编译器会优先选用非常量版本的函数。
 

const_cast 和重载

const_cast 可以用于函数的重载。
 
当函数的实参是常量时,返回的结果仍然是常量的引用:
这个函数的参数和返回值都是const string的引用。可以对两个非常量的string实参调用这个函数,但返回的结果仍然是const string的引用。因此需要一种新的shorterString函数,当它的实参不是常量时,得到的结果是一个普通的引用,使用const_cast可以做到这一点:
 

调用重载函数

函数匹配也叫做 重载确定,是指编译器将函数调用与一组重载函数中的某一个进行关联的过程。
编译器首先将调用的实参与重载集合中每一个函数的形参进行比较,然后根据比较的结果决定到底调用是哪个函数。
调用重载函数时有三种可能的结果:
  • 编译器找到一个与实参最佳匹配的函数,并生成调用该函数的代码
  • 编译器找不到任何一个函数与实参匹配,发出无匹配的错误信息
  • 有一个以上的函数与实参匹配,但每一个都不是明显的最佳选择,此时编译器发出二义性调用的错误信息
 

重载与作用域

一般来说,将函数声明置于局部作用域内不是一个明智的选择。
在不同的作用域中无法重载函数名。一旦在当前作用域内找到了所需的名字,编译器就会忽略掉外层作用域中的同名实体。
 
C++中,名字查找发生在类型检查之前。假设把print(int)和其他print函数声明放在同一个作用域中,则它将成为另一种重载形式。此时,因为编译器能看到所有三个函数,上述调用的处理结果将完全不同:
 
 

函数匹配

函数实参类型与形参类型越接近,它们匹配得越好。
函数匹配的第一步是选定本次调用对应的重载函数集, 集合中的函数称为候选函数(candidate function)
  • 与被调用的函数同名
  • 其声明在调用点可见
 
第二步考察本次调用提供的实参,然后从候选函数中选出能被这组实参调用的函数,这些新选出的函数称为可行函数(viable function)
  • 形参数量与函数调用所提供的实参数量相等
  • 每个实参的类型与对应的形参类型相同,或者能转换成形参的类型
如果没找到可行函数,编译器讲报告无匹配函数的错误。
调用重载函数时应该尽量避免强制类型转换。
 

实参类型转换

为了确定最佳匹配,编译器将实参类型到形参类型的转换划分成几个等级如下所示:
  1. 精确匹配 包括以下情况:
      • 实参类型和形参类型相同
      • 实参从数组类型或函数类型转换成对应的指针类型
      • 向实参添加顶层 const 或者从实参中删除顶层 const
  1. 通过 const 转换实现的匹配
  1. 通过类型提升实现的匹配
  1. 通过算术类型转换或指针转换实现的匹配
  1. 通过类类型转换实现的匹配
所有算术类型转换的级别都一样。
如果重载函数的区别在于它们的引用或指针类型的形参是否含有底层 const,或者指针类型是否指向 const,则调用发生时编译器通过实参是否是常量来决定函数的版本。
  • C++
  • 返回类型和return内联函数和constexpr函数
    目录