在C ++中,数组索引的默认大小为size_t,这是大多数x86-64平台上的64位无符号 64位整数。我正在为自己的高性能计算库构建自己的std :: vector类(主要原因之一是我希望该类能够获得指针的所有权,而std :: vector却没有提供)。对于数组索引的类型,我正在考虑使用以下任一方法:
与无符号整数相比,使用有符号整数的优势很多,例如
for (index_t i = 0; i < v.size() - 1; ++i)
Run Code Online (Sandbox Code Playgroud)
的工作方式就像是假设的(使用无符号整数,当v的大小为0时,此循环会变得疯狂)
for (index_t i = v.size() - 1; i >= 0; --i)
Run Code Online (Sandbox Code Playgroud)
像预期的那样工作,还有许多其他优点。在性能方面,它甚至看起来要好一些
a + 1 < b + 1
Run Code Online (Sandbox Code Playgroud)
可以减少为带符号整数的<b(未定义溢出),而对于无符号整数则不能。唯一有利的性能明智的做法是,可以将/ = 2简化为使用无符号整数的移位操作,而不是使用有符号整数的移位操作。
我想知道为什么C ++委员会决定对size_t 使用无符号整数,因为这似乎带来了很多麻烦,并且只有很少的优点。
在标准中使用无符号类型作为索引或大小的动机是基于仅与 16 位机器相关的约束。C++ 中任何整数类型的自然类型是
int,这就是可能应该使用的类型;正如您所注意到的,在 C++ 中尝试使用无符号类型作为数值是充满问题的。如果您担心尺寸太大以至于无法放入int,ptrdiff_t
将是合适的;毕竟,这是指针或迭代器相减结果的类型。(事实上,
v.size()它的类型v.end() - v.begin()与标准库中的设计缺陷不同。)
对我来说,无符号大小总是最有意义的,因为数组中不能有 -32 个元素,因此始终将大小/长度视为有符号数量是非常非常可怕的。
您提到的极端情况可以进行编码,例如,如果第一种情况为空,您可以在进入循环之前中止循环v(这看起来不太常见,迭代除最后一个元素之外的所有元素?)。