繁体   English   中英

为什么std :: abs返回签名类型

[英]Why does std::abs return signed types

我得到的签署对无符号比较时,我比较一个警告std::abs(int)对一个unsigned 实际上, std::abs返回有符号值。 为什么选择这个? 它将解决负值的问题,其绝对值不能用有符号的类型表示。

然后,是否有比这更清洁(即没有演员表)的东西以避免警告?

#include <cassert>
#include <cstdlib>

// max(1, lhs + rhs). (lhs must be > 0)
unsigned add(unsigned lhs, int rhs)
{
  return
    (0 < rhs || static_cast<unsigned>(-rhs) < lhs
     ? rhs + lhs
     : 1);
}

int main()
{
  assert(add(42, -41) == 1);
  assert(add(42, 0) == 43);
  assert(add(42, 1) == 43);
  assert(add(42, -51) == 1);
}

简短的回答是这样做是为了使abs的返回类型与其输入类型相同。 这正是你想要的,大多数时候。

大多数情况下,当调用abs时,你正在处理一个方程式,其中所有元素都是相同的类型(或者你会得到警告),并且你想要使用该等式中某个变量的大小。 这并不意味着您想要更改等式中某个变量的类型。 这会给你提到的那种问题/警告。

因此,简而言之,在要求签名变量的绝对值时,想要相同的输入和输出类型更为常见和更自然。 价值的大小通常不被用作指数。

在c ++ 11中,您可以自己编写以进行自动转换:

#include <utility>

template< typename T >
typename std::make_unsigned<T>::type  abs( T x )
{
    //We need to cast before negating x to avoid the overflow.
    return x < 0? -static_cast<std::make_unsigned<T>::type>(x) : x;
}

我用-Wall选项尝试了它,没有任何警告。

这是别无选择,那就是定义。 abs通过模板实现,该模板返回存储原始值的类型。 结果始终有效,因为有符号整数的绝对值始终适合其原始数据类型。 对目标数据类型的显式强制转换应该足以消除任何警告......

暂无
暂无

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

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