How to determine which overloaded function is being called?

#include <iostream> #include <cmath> using namespace std; float f (int a, int b) { return (a + b); } float f (float a, float b) { return (round(a + b)); } int main () { cout << "Hello World!" << endl; int int1 = 1; int int2 = 2; float float1 = 1.2f; float float2 = 1.4f; cout << f(int1, int2) << endl; // output: 3 cout << f(float1, float2) << endl; // output: 2 cout << f(int1, float2) << endl; // output: 2 return 0; } 
  • Why does the last conclusion use the second definition of f ?

  • In general, how to determine which overloaded function definition will be used when there is an exact correspondence between the number and types of arguments between function definitions and a function call?

+4
source share
3 answers

After trying to determine in the standard why one overload is preferable over another, I came to the conclusion that it should not, overload does not have a better conversion sequence than the other in the case of f( int1, float2 ) and the code should not be compiled. If your compiler accepts it, there may be an implementation error.

On the second question, the standard defines transformations that can be used to correspond to a function call, and also determines the rank for those transformations that serve as partial ordering (called a better transformation than). The compiler will always choose the best conversion, and if there is no better conversion, the program will be poorly formed, as in the example.

Code ambiguity checking with different compilers:

GCC:

 conv.cpp:22: error: call of overloaded 'f(int&, float&)' is ambiguous conv.cpp:5: note: candidates are: float f(int, int) conv.cpp:9: note: float f(float, float) 

clank:

 conv.cpp:22:13: error: call to 'f' is ambiguous cout << f(int1, float2) << endl; // output: 2 ^ conv.cpp:5:7: note: candidate function float f (int a, int b) { ^ conv.cpp:9:7: note: candidate function float f (float a, float b) { ^ 

MSVS 2010 (thanks to Xeo):

 error C2666: 'f' : 2 overloads have similar conversions src\main.cpp(2): could be 'void f(int,int)' src\main.cpp(1): or 'void f(float,float)' while trying to match the argument list '(int, float)' 
+4
source

All you need to know and much more: http://www.learncpp.com/cpp-tutorial/76-function-overloading/

In fact, the second one is selected, because if an exact match is not possible and a match in advance is not possible, the conversion is performed (from the first parameter from int to float ).

0
source

In very simple expressions, if you convert int to float , you do not lose any information; if you convert float to int , you will lose the decimal part of the number. If the compiler cannot find an exact overload match, it will select the one that causes the least loss of information.

0
source

Source: https://habr.com/ru/post/1388741/


All Articles