【问题标题】:How to determine which overloaded function is called?如何确定调用了哪个重载函数?
【发布时间】:2013-01-22 10:33:06
【问题描述】:
#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;
}
  1. 为什么最后一个输出使用f的第二个定义?

  2. 一般来说,当函数定义和函数调用之间的参数数量和类型不完全匹配时,如何确定将使用哪个重载函数定义?

    李>

【问题讨论】:

  • 我想你的意思是:float float1 = 1.2;float float2 = 1.4;
  • 我的直接答案是int -&gt; floatfloat -&gt; int 的转换效果更好。有趣的是,我无法在声明的标准中找到引用。
  • 您使用的是什么编译器/版本?验证标准后,我认为代码应该会触发错误,因为调用f( int1, float2 )不明确。 GCC 和 Clang 同意。
  • MSVC(至少 10 个)实际上也同意。

标签: c++ overloading


【解决方案1】:

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

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

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

海合会:

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)'

【讨论】:

【解决方案2】:

所有您需要知道的以及更多信息:http://www.learncpp.com/cpp-tutorial/76-function-overloading/

基本上选择了第二个,因为如果不可能完全匹配并且不可能通过提升进行匹配,则通过转换(第一个参数从intfloat)进行匹配。

【讨论】:

  • 现在的问题是,在标准中,int-&gt;float 转换被认为是比float-&gt;int 转换更好的转换顺序,两者都是浮点积分转换
  • 我怀疑 float->int 被认为更好,因为你会丢失信息。
  • 我们同意这一点:考虑更好的转换可能会丢失信息是没有意义的,但这可能是在我无法找到的标准中的某个地方定义的。
  • 经过相当长的时间检查标准,没有条款确定int-&gt;float转换比float-&gt;int转换更好。转换序列不能按标准中的更好关系排序,代码不应该编译。再次看来,常识和标准并不总是相同的。 (我也用 gcc 和 clang 验证了这一点)
【解决方案3】:

简单来说,如果您将int 转换为float,您不会丢失任何信息;如果将float 转换为int,则会丢失数字的小数部分。如果编译器找不到精确的重载匹配,它将选择导致信息丢失最少的那个。

【讨论】:

    猜你喜欢
    • 2010-11-15
    • 2010-11-19
    • 2010-09-27
    • 1970-01-01
    • 1970-01-01
    • 2010-12-19
    • 1970-01-01
    • 1970-01-01
    • 2011-03-21
    相关资源
    最近更新 更多