3

当我想否定一些类型std::size_t时,我通常会这样做-static_cast<int>(number)。但是,我知道该数字可能不适合int. 所以,我的问题是什么是安全的便携方式来做到这一点?

4

4 回答 4

3

没有安全的便携式方法可以做到这一点。

size_t是无符号类型。不能保证有任何有符号整数类型大到足以容纳 的最大值size_t

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

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

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

于 2012-08-22T21:25:44.140 回答
1

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

要检测结果是否不适合:

(number <= std::numeric_limits<int>::max()) ? -static_cast<int>(number) : ...
于 2012-08-22T21:25:34.810 回答
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! */ }
于 2012-08-22T21:27:49.697 回答
1

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

于 2012-08-22T21:28:04.890 回答