#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;
}
  • 为什么最后一个输出使用f的第二个定义?
  • 通常,当在函数定义和函数调用之间参数的数量和类型不完全匹配时,如何确定将使用哪个重载函数定义?
  • 最佳答案

    在尝试确定标准中为什么一个重载优先于另一个重载之后,我得出了这样的结论:在f( int1, float2 )的情况下,没有一个重载比另一个重载具有更好的转换顺序,并且该代码不应该编译。如果您的编译器接受它,则说明实现中可能存在错误。

    从第二个问题开始,该标准定义了可用于匹配对函数调用的转换,并且还定义了用作部分排序的转换的等级(称为更好的转换)。编译器将始终选择最佳转换,如果没有最佳转换,则程序将如示例中那样格式错误。

    使用不同的编译器验证代码的歧义性:

    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)
    

    铛:
    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(感谢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)'
    

    10-08 11:59