为什么使用不匹配的参数调用重载函数仍然有效

why does calling an overloaded function with arguments that don't match still work

本文关键字:函数 重载 有效 调用 参数 不匹配 为什么      更新时间:2023-10-16

我无法解释为什么第二次调用(B(没有给出任何错误,因为有两个char元素,并且此调用没有确定的匹配。

为什么它被称为第二个(2.(,而不是第一个(1.(版本?

我注意到有一些自动转换。我不明白的是为什么'a'被提升为 int 而'c'没有。

// 1.
int fun(int a, int b)
{
return a + b;
}
// 2.
int fun(int a, char b)
{
return b - a;
}
// 3 
int fun(float a, float b)
{
return a * b;
}
int main() {
//      A.          B.              C.
cout << fun(1,0) << fun('a','c') << fun(2.f,2.f);
return 0;
}

重载解析的规则很复杂。在这种情况下,func('a','c')更喜欢int fun(int a, char b)的原因是因为它意味着隐式转换序列最少。查看每个案例:

int fun(int a, int b)有两个参数不是完全匹配的。它需要两次从char晋升到int

int fun(int a, char b)有一个完全匹配和一个从charint的晋升。

int fun(float a, float b)有两个参数不是完全匹配的,需要从char转换为float(比促销更糟糕(。

你已经有了答案,隐式转换正在发生。char是特殊的小数字;您可以通过coutint<cstdint>int8_t来验证这一点。至于为什么选择2而不是1,这与匹配更多有关。重载 2 与其中一个参数完全匹配,而其他参数都不匹配。由于第一个参数可以隐式转换,因此这是最接近的匹配项,因此也是编译器选择的重载。

'c'是一个char。调用函数 1 需要将其提升为int。另一方面,对于函数 2,它不必进行转换(它是标识转换(。在对要调用的重载集中的可行函数进行排序时,标准如下

[过度.匹配.最佳]

1 根据这些定义,可行的函数 F1 定义为 一个比另一个可行的函数 F2 更好的函数,如果对于所有参数 i, ICSi(F1( 不是比ICSi(F2( 更差的转换序列,并且然后

  • 对于某些参数j,ICSj(F1( 是比ICSj(F2( 更好的转换序列,或者,

这就是我们这里的情况。与另一个重载相比,第二个参数的隐式转换序列在一个重载中更好。所以它被选中了。

如果删除fun(int a, char b)将调用fun(int a, int b)函数。我这样说只是作为其他人所说的话的一个例子。 选择fun(int a, char b)是因为它比fun(int a, int b)匹配得更好。char 被隐式转换为其 ASCII 整数值,以便匹配函数参数。