【问题标题】:std::abs for "unsigned long long int" data typestd::abs 用于“unsigned long long int”数据类型
【发布时间】:2013-06-19 10:37:18
【问题描述】:

为什么会出现这个错误

 C2668: 'abs' : ambiguous call to overloaded function

对于这样的简单代码

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

删除std:: 后错误仍然存​​在。但是,如果我使用 int 数据类型(具有较小的值)没有问题。

传统的解决方案是手动检查

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

这是唯一的解决方案吗?

【问题讨论】:

  • 为什么要abs一个无符号类型? (不是反问)
  • @Mario 他们想要消除两个无符号值之间的差异
  • 无符号类型不是环绕吗? a-b 的结果不是 -10000000000000 而是 std::numeric_limits&lt;unsigned long long&gt;::max()-10000000000000(仍然是 unsigned long long)。
  • @mahmood 请注意&lt;&lt; 的优先级高于?:,因此请记住括号! en.cppreference.com/w/cpp/language/operator_precedence

标签: c++ visual-studio-2010


【解决方案1】:

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

如果您的范围适合,您可以使用解决方案转换为已签名 long long。我几乎不会建议那样做,尤其是如果将实现放在一个仅执行此操作的函数中。

【讨论】:

    【解决方案2】:

    您包括&lt;cmath&gt;,因此使用“floating-point abs”。

    integer abs”在&lt;cstdlib&gt; 中声明。

    但是,unsigned long long int 没有重载(ab 都是,因此 a-b 也是),long long int 的重载只存在于 C++11 之后。

    【讨论】:

    【解决方案3】:

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

    1.84467e+19
    

    改为包含&lt;cstdlib&gt;。现在的错误是:

    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 位值差异的任何可能结果。如果您可以确认这不会成为问题,请按照建议使用演员表。但是,如果您不知道,您可能需要重新考虑您实际想要实现的目标。

    【讨论】:

      【解决方案4】:

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

      使用labs(a-b),因为您使用的是long,这应该可以解决您的问题。

      【讨论】:

      • @mahmood 是的,如果 a
      • 是的,@nos 说的,对不起,我认为这是常识?
      • longlong long 不同。
      猜你喜欢
      • 2016-07-29
      • 1970-01-01
      • 1970-01-01
      • 2012-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-20
      • 1970-01-01
      相关资源
      最近更新 更多