6

Why should I get this error

 C2668: 'abs' : ambiguous call to overloaded function

For a simple code like this

#include <iostream>
#include <cmath>
int main()
{
  unsigned long long int a = 10000000000000;
  unsigned long long int b = 20000000000000;
  std::cout << std::abs(a-b) << "\n";   // ERROR
  return 0;
}

The error still presents after removing std::. However if I use int data type (with smaller values) there is no problem.

The traditional solution is to check that manually

std::cout << (a<b) ? (b-a) : (a-b) << "\n";

Is that the only solution?

4

4 回答 4

11

检查似乎是唯一真正好的解决方案。替代方案需要比您的类型更大的类型和非标准扩展才能使用它。

如果您的范围适合,您可以使用解决方案转换为已签名的 long long。我几乎不会建议这种方式,特别是如果将实现放置在仅执行此操作的函数中。

于 2013-06-19T10:51:42.033 回答
5

您正在包括<cmath>并因此使用“浮点abs”。

整数abs”在 中声明<cstdlib>

但是,对于unsigned long long int(both aand bare,因此a-b也是) 没有重载,并且 for 的重载long long int仅存在于 C++11 之后。

于 2013-06-19T10:46:05.073 回答
1

首先,您需要包含正确的标题。正如 gx_ 所指出的,<cmath>它有一个浮点 abs 并且在我的编译器上它实际上可以编译,但结果可能不是你所期望的:

1.84467e+19

<cstdlib>改为包括。现在错误是:

main.cpp:7:30: error: call of overloaded ‘abs(long long unsigned int)’ is ambiguous
main.cpp:7:30: note: candidates are:
/usr/include/stdlib.h:771:12: note: int abs(int)
/usr/include/c++/4.6/cstdlib:139:3: note: long int std::abs(long int)
/usr/include/c++/4.6/cstdlib:173:3: note: long long int __gnu_cxx::abs(long long int)

正如你所看到的,这个函数没有unsigned重载,因为计算类型的绝对值是unsigned没有意义的。

我看到答案建议您将unsigned类型转换为已签名的类型,但我相信这是危险的,除非您真的知道自己在做什么!让我先问一下,预期的值范围是多少ab您将要进行操作?如果两者都低于2^63-1我强烈建议只使用long long int. 但是,如果这不是真的,请注意您的值程序:

a=0, b=1

a=2^64-1, b=0

将产生完全相同的结果,因为您实际上需要 65 位来表示 2 个 64 位值差异的任何可能结果。如果您可以确认这不会成为问题,请按照建议使用演员表。但是,如果您不知道,您可能需要重新考虑您实际想要实现的目标。

于 2013-06-19T10:57:29.227 回答
-2

因为在使用 C 的 C++ 之前,您曾经为每种不同的类型使用 abs、fabs、labs,所以 c++ 允许对 abs 进行重载,在这种情况下,它不理解或对您的重载不满意。

在使用 long 时使用labs(a-b)查看,这应该可以解决您的问题。

于 2013-06-19T10:43:48.510 回答