【问题标题】:Ambiguity error using overload in c++在 C++ 中使用重载的歧义错误
【发布时间】:2017-01-13 08:31:33
【问题描述】:

我尝试过使用浮点和整数的重载。当我只使用整数时,代码工作正常,但是当我包含浮点数时,它给了我错误。代码如下:

#include <iostream>
using namespace std;

int calculate(int x,int y);
float calculate(float x,float y);
const int MAININT=4;

int main()
{
    int result=calculate(5,5);
    float fresult=calculate(7.5,7.5);                 LINE X
    cout << (result + MAININT + fresult);             LINE Y
    return 0;
}

int calculate(int x,int y)
{
    int result=x*y;
    return result;
}

float calculate(float x,float y)
{
    int result=x*y;
    return result;
}

通过删除 LINE X 并从 LINE Y 删除,代码不会给我任何错误。所以我认为 LINE X 一定有问题,但我不明白为什么会出错。

我得到的错误信息是:

[Error] call of overloaded 'calculate(double, double)' is ambiguous
[Note] candidates are:
[Note] int calculate(int, int)
[Note] float calculate(float, float)

我不理解错误消息,所以我没有包含它们。我从songyuanyao的回答中理解了我做错了什么,但是下次我会从一开始就在我的问题中包含错误消息,以便更容易看到我在代码中做错了什么。

【问题讨论】:

  • 错误信息应该有助于理解。你读了吗?
  • 当您遇到此类问题时,发布确切的错误消息
  • 因不包含错误消息而投反对票。智能用户可能会搜索错误消息中的固定文本。没有错误,他们就找不到这个问题和答案。

标签: c++ overloading overload-resolution


【解决方案1】:

因为7.5double(参见floating point literal),而不是float;和隐式转换为intfloat 被视为相同的排名。

如果您在此处假设 7.5float,则可以使用后缀 fF 使其成为 float 文字。例如

float fresult = calculate(7.5f, 7.5f); // 7.5f is a float literal; no ambiguity

或者使用显式转换:

float fresult = calculate(static_cast<float>(7.5), static_cast<float>(7.5));

【讨论】:

  • 太棒了!现在代码可以正常工作了。谢谢!
【解决方案2】:

您应该已经发布了本身不言自明的错误消息。错误消息提到了候选函数以及它们如何不完全兼容

error: call of overloaded 'calculate(double, double)' is ambiguous
     float fresult=calculate(7.5,7.5);                
                                    ^
note: candidate: int calculate(int, int)
 int calculate(int x,int y);
     ^
note: candidate: float calculate(float, float)
 float calculate(float x,float y);

默认情况下,浮点文字(在您的情况下为7.5)的类型为 double

这里是确定浮点字面量类型的后缀列表:

  1. (无后缀)定义double
  2. f F 定义 float
  3. l L 定义 long double

【讨论】:

    【解决方案3】:

    虽然其他人已经告诉您歧义错误的来源,但我很惊讶没有人提到解决问题的最简单方法:只需使用double 而不是float

    就像int 应该是整数的默认选择一样,double 应该是浮点数的默认选择。 float 用于非常特殊的用例,它们都不可能适用于您的情况。请参阅 Software Engineering Stack Exchange 上的 "When do you use float and when do you use double"

    作为遵循本指南的副作用,您在此处的特定问题消失了:

    #include <iostream>
    using namespace std;
    
    int calculate(int x,int y);
    double calculate(double x, double y);
    const int MAININT=4;
    
    int main()
    {
        int result=calculate(5,5);
        double fresult=calculate(7.5,7.5);
        cout << (result + MAININT + fresult);
        return 0;
    }
    
    int calculate(int x,int y)
    {
        int result=x*y;
        return result;
    }
    
    double calculate(double x, double y)
    {
        double result=x*y; // the `int` here was a mistake in your original code anyway
        return result;
    }
    

    一些进一步的建议:

    • 避免using namespace std;
    • 为预处理器宏保留ALL_CAPS

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-13
      • 1970-01-01
      • 1970-01-01
      • 2017-05-02
      • 2021-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多