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

你。 提交于 2020-01-15 06:28:08

问题


I am not able to explain why the second call (B) doesn't give any errors as there are two char elements, and there is no certain match for this call.

Why it is called the second one (2.), but not the first (1.) version?

I've noticed that there are some automatic conversions. The thing that i don't get is why 'a' is promoted to int and 'c' isn't.

// 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;
}

回答1:


The rules for overload resolution are complicated. In this case, the reason func('a','c') prefers int fun(int a, char b) is because it implies the fewest implicit conversion sequences. Looking at each case :

int fun(int a, int b) has two arguments that are not perfect matches. It requires two promotions from char to int.

int fun(int a, char b) has one exact match and one promotion from char to int.

int fun(float a, float b) has two arguments that are not perfect matches that require conversions (worse than promotion) from char to float.




回答2:


You've already got the answer, an implicit conversion is happening. chars are special small numbers; you can verify this by coutint an int8_t from <cstdint>. As to why 2 was selected and not 1, it has to do with what matches more. Overload 2 exactly matches one of the parameters and none of the others do. And because the first parameter can be implicitly converted, this is the closest match and therefore the overload that the compiler chooses.




回答3:


'c' is a char. Calling function 1 will require promoting it to an int. On the other hand, for function 2 it doesn't have to undergo a conversion (it's the identity conversion). When ranking viable functions to call in an overload set, the standard says as follow

[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,

Which is our case here. The implicit conversion sequence for the second argument is better in one overload compared to the other. So it gets chosen.




回答4:


If you remove fun(int a, char b) the fun(int a, int b) function will be called. I only say this as an example of what the others are saying. fun(int a, char b) is chosen because it matches better than fun(int a, int b). The char is implicitly cast to its ASCII integer value in order to match the function parameters.



来源:https://stackoverflow.com/questions/59532786/why-does-calling-an-overloaded-function-with-arguments-that-dont-match-still-wo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!