在 c++ 中使用重载的歧义错误

Ambiguity error using overload in c++

本文关键字:歧义 错误 重载 c++      更新时间:2023-10-16

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

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

通过删除 X 行并从 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)

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

因为7.5是一个double(参见浮点文字),而不是一个float;隐式转换为intfloat被认为是相同的排名。

如果你的假设7.5在这里float,你可以使用后缀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));

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

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

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

就像int应该是整数的默认选择一样,double应该是浮点数的默认选择。 float适用于非常特殊的用例,这些用例都可能不适用于您的情况。请参阅"何时使用float,何时使用double",请参阅Software Engineering Stack Exchange。

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

#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