为什么c ++ STL使用unsigned in size()函数? [重复]

问题描述 投票:1回答:2

这个问题在这里已有答案:

我在使用这样的循环时遇到了问题,

//vector<int> sides;
for (int i = 0; i < sides.size()-2; i++) {
  if (sides[i] < sides[i+1] + sides[i+2]) {
    ...
  }
}

问题是size()方法使用无符号数。因此,大小小于2的向量会产生不确定的结果。

我知道我应该为循环使用无符号变量,但它不能解决问题。所以我不得不通过类型转换或使用某些条件来处理它。

我的问题是为什么STL使用unsigned int来消除负面索引访问冲突并产生更多问题?

c++ stl size containers sizeof
2个回答
3
投票

原因是确定任何对象大小的运算符sizeof返回size_t类型的值。因此,例如标准C函数strlen也有返回类型size_t

因此,采用标准容器也将其大小作为size_t类型的值返回。

至于循环,则可以例如以下方式重写它

for ( size_t i = 0; i + 2 < sides.size(); i++) {
  if (sides[i] < sides[i+1] + sides[i+2]) {
    ...
  }
}

4
投票

决定容器将在90年代使用未签名的索引和大小。

从表面上看,这似乎很明智;我的意思是,容器的大小和索引不能是负数。它还允许稍大的最大值,特别是在16位系统上。

它现在被认为是一个错误;你的代码只是其中一个原因之一。 std2几乎肯定会使用ptrdiff_t的签名合作伙伴size_t来获取尺寸和索引。

注意1u-2是定义的行为;它是-1转换为无符号,保证是该类型的最大无符号值。

您可以通过多种方式修复代码,包括:

for (int i = 0; i+2 < sides.size(); i++) {
  if (sides[i] < sides[i+1] + sides[i+2]) {

要么

for (int i = 0; i < (std::ptrdiff_t)sides.size()-2; i++) {
  if (sides[i] < sides[i+1] + sides[i+2]) {

第二个可以在接近内存空间限制大小的容器上中断;在64位系统上这不是问题,在32位系统和char矢量上,你可以创建一个足够大的矢量。

© www.soinside.com 2019 - 2024. All rights reserved.