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

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

我无法解释为什么第二次调用 (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;
}

您已经得到答案,正在进行隐式转换。 chars是特殊的小数;您可以通过 coutint an int8_t from <cstdint> 来验证这一点。至于为什么选择2而不是1,这与匹配的更多有关。重载 2 与其中一个参数完全匹配,其他 none 匹配。并且因为第一个参数可以隐式转换,这是最接近的匹配,因此是编译器选择的重载。

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

[over.match.best]

1 Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then

  • for some argument j, ICSj(F1) is a better conversion sequence than ICSj(F2), or,

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

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

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

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

int fun(float a, float b) 有两个不完全匹配的参数,需要从 charfloat.

的转换(比提升更糟糕)

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