我可以在不丢失数据的情况下将 unsigned long 转换为 size_t 吗?

Can I cast a unsigned long to size_t without loss of data?

size_t 是无符号整数类型,由(例如)sizeof 返回。因此,我可以将 unsigned long 投入其中吗?会出现什么问题?我应该使用 static_castreinterpret_cast 还是其他?

编辑:

我想将字符串转换为 unsigned long,然后将其转换为 size_t:

size_t StringHandling::ConvertSize_T (std::string& input, int base)
{
    return static_cast<size_t>(std::stoul(input, 0, base));
}

你能安全地将 std::size_t 转换为 unsigned long 吗?

一般……没有.

如果 unsigned long 在您的系统上与 std::size_t 具有相同的宽度,那么您可以使用简单的 static_cast 来摆脱它。但为什么要冒险呢?如果没有,并且这在当今存在的系统上绝非不可能,那么您可能会截断 half 您的值 space — 如果您要从64 位到 32 位,即丢失了 18 quintillion、400 和 forty-six quadrillion、700 和 forty-four trillion 可能的值!!

如果您从一个函数中得到一个 std::size_t,该函数决定它需要该类型来表示其结果的所有可能值,请保留一个 std::size_t.


你能安全地将 unsigned long 转换为 std::size_t 吗?

当然可以。从技术上讲,我认为没有任何理由使后者 比前者更宽(或什至至少与前者一样宽)(它只需要至少 16 位宽),但您将 hard-pressed 找到任何不是这种情况的系统。


你能安全地混合使用 std::stoulstd::size_t 吗?

这取决于您的项目要求。根据上述,将 std::stoul 的结果转换为 std::size_t 可能没问题。

但是,std::stoul 本身呢?您是否希望字符串包含适合 std::size_t 但不适合 unsigned long 的数值?如果是这样,那么您的字符串解析是错误的,而不是转换,您将需要找到一种更合适的方法来从您的流中提取如此大的数字。


tl;dr:尽量不要混合类型。计算出您的输入的预期数值范围,相应地选择合适的类型,然后 在整个管道中坚持使用它

如果你的意思是理论上的、语言律师的方式,那么答案是否定的:

According to the 1999 ISO C standard (C99), size_t is an unsigned integer type of at least 16 bit (see sections 7.17 and 7.18.3).

所有 C99 标准保证它至少是 16 位类型。

然而,在现代 Intel/ARM 架构的现实世界中,size_t 通常是本机寄存器大小,因此在 32 位架构上为 32 位,在 64 位架构上为 64 位位架构。您应该始终能够将 int 存储在 size_t 中,但反之则不行。

Should I use static or reinterpret cast, or another?

此转换为静态转换,重新解释用于重新解释指向不同不相关类型的指针。