我无法解释为什么第二次调用(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)
有一个完全匹配和一个从char
到int
的晋升。
int fun(float a, float b)
有两个参数不是完全匹配的,需要从char
转换为float
(比促销更糟糕(。
你已经有了答案,隐式转换正在发生。char
是特殊的小数字;您可以通过cout
int<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 整数值,以便匹配函数参数。