当我想否定一些std::size_t
类型时,我通常会-static_cast<int>(number)
。但是,我知道这个数字可能不适合int
。那么,我的问题是什么是一种安全便携的方式呢?
答案 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
),您将无法以“否定”格式描述这些值带有一个额外的标志变量,用于指定值的符号。那当然不再是“便携式”......