否定一些类型std :: size_t的安全方法

时间:2012-08-22 21:18:11

标签: c++

当我想否定一些std::size_t类型时,我通常会-static_cast<int>(number)。但是,我知道这个数字可能不适合int。那么,我的问题是什么是一种安全便携的方式呢?

4 个答案:

答案 0 :(得分:3)

没有安全便携的方法来做到这一点。

size_t是无符号类型。无法保证任何符号整数类型足以保持最大值size_t

如果您能够假设您否定的值不是太大,您可以将其转换为long long(如果您的编译器支持它)或long(如果它不是“T):

size_t s = some_value;
long long negative_s = -(long long)s;

如果您担心溢出,可以在转换之前将s的值与LLONG_MAX进行比较。

答案 1 :(得分:1)

-static_cast<int>(number) 安全; static_cast的结果是实现定义的,如果它不适合int

检测结果是否不合适:

(number <= std::numeric_limits<int>::max()) ? -static_cast<int>(number) : ...

答案 2 :(得分:1)

安全方法检查变量是否适合相应的签名类型:

typedef std::size_t my_uint;
typedef typename std::make_signed<my_uint>::type my_int;

my_uint n = /* ... */;

if (n > std::numeric_limits<my_int>::max()) { /* Error! */ }

my_int m = -static_cast<my_int>(n);

您需要#include <limits><type_traits>

(或将所有内容包装成一行:)

if (n > std::numeric_limits<typename std::make_signed<decltype(x)>::type>::max()) { /* Error! */ }

答案 3 :(得分:1)

我认为你有一个固有的问题,你不能使用std::size_t来否定std::ssize_t的上半部分的值,因为std::ssize_t只能描述std::size_t范围内的一半值。例如,如果您的unsigned char值为255,则永远不会得到signed char的值为-255 ...您需要更大的类型,例如signed short。如果std::size_t是您平台的最大整数容器,那么如果不指定某些自定义数据类型(例如struct),您将无法以“否定”格式描述这些值带有一个额外的标志变量,用于指定值的符号。那当然不再是“便携式”......