简体   繁体   English

std :: abs用于“unsigned long long int”数据类型

[英]std::abs for “unsigned long long int” data type

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:: . 删除std::后仍会出现错误。 However if I use int data type (with smaller values) there is no problem. 但是,如果我使用int数据类型(具有较小的值),则没有问题。

The traditional solution is to check that manually 传统的解决方案是手动检查

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

Is that the only solution? 这是唯一的解决方案吗?

The check seem the only really good solution. 检查似乎是唯一真正好的解决方案。 Alternatives require type bigger than yours and nonstandard extension to use it. 替代品需要比您更大的类型和非标准扩展才能使用它。

You can go with solutions casting to signed long long if your range fits. 如果您的范围合适,您可以使用解决方案投射到签名长。 I would hardly suggest that way, especially if the implementation is placed in a function that does only that. 我几乎不建议这样做,特别是如果将实现放在只执行该操作的函数中。

You are including <cmath> and thus using the " floating-point abs ". 你包括<cmath> ,因此使用“ 浮点abs ”。

The " integer abs " is declared in <cstdlib> . 整数abs ”在<cstdlib>声明。

However, there is no overload for unsigned long long int (both a and b are, thus ab is, too), and the overload for long long int only exists since C++11. 但是, unsigned long long int没有重载( ab都是,因此ab也是如此), long long int的重载仅存在于C ++ 11之后。

First, you need to include the correct header. 首先,您需要包含正确的标头。 As pointed out by gx_, <cmath> has a floating-point abs and on my compiler it actually compiles, but the result is probably not the one you expected: 正如gx_所指出的, <cmath>有一个浮点abs,在我的编译器上它实际编译,但结果可能不是你想要的那个:

1.84467e+19

Include <cstdlib> instead. 请改为包含<cstdlib> Now the error is: 现在的错误是:

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)

As you can see, there is no unsigned overload of this function, because computing an absolute value of something which is of type unsigned makes no sense. 正如您所看到的,此函数没有unsigned重载,因为计算unsigned类型的绝对值是没有意义的。

I see answers suggesting you to cast an unsigned type to a signed one, but I believe this is dagereous , unless you really know what you are doing! 我看到答案建议你将一个unsigned类型转换为签名类型,但我相信这是dagereous ,除非你真的知道你在做什么! Let me ask first what is the expected range of the values a and b that you are going to operate on? 让我先问一下你要操作的ab值的预期范围是多少? If both are below 2^63-1 I would strongly suggest to just use long long int . 如果两者都低于2^63-1我强烈建议只使用long long int If that is not true however, let me note that your program for the values: 如果不是这样,请注意你的价值观程序:

a=0, b=1

and

a=2^64-1, b=0

will produce exactly the same result , because you actually need 65 bits to represent any possible outcome of a difference of 2 64-bit values. 将产生完全相同的结果 ,因为您实际上需要65位来表示2个64位值的差异的任何可能结果。 If you can confirm that this is not going to be a problem, use the cast as suggested. 如果您可以确认这不会成为问题,请按照建议使用强制转换。 However, if you don't know, you may need to rethink what you are actually trying to achieve. 但是,如果您不知道,您可能需要重新考虑您实际想要实现的目标。

Because back before C++ with C you used to have use abs, fabs, labs for each different type, c++ allows overloading of abs, in this case it doesn't understand or isn't happy with your overload. 因为在使用C的C ++之前,你曾经使用过abs,fabs,labs来处理每种不同的类型,c ++允许重载abs,在这种情况下它不理解或不满意你的重载。

Use labs(ab) seeing as you're using longs, this should solve your problem. 使用labs(ab)看到你正在使用多头,这应该可以解决你的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM