矢量大小自动失败

时间:2018-05-26 11:52:45

标签: c++ c++11 vector auto

我正在尝试使用auto推断出类型。

for (auto i = remaining_group.size() - 1; i >= 0; --i) {
    std::cout << i;
}

我得到非常大的数字,如18446744073709534800,这是不可预期的。当我将auto更改为int时,这是我预期的0到39之间的数字。

这里有auto失败的原因吗?

remaining_group的类型为std::vector<lidar_point>lidar_point的结构类似于:

struct LidarPoint {
  float x;
  float y;
  float z;
  uint8_t field1;
  double field2;
  uint8_t field3;
  uint16_t field4;
}

3 个答案:

答案 0 :(得分:2)

使用auto时,i的类型为std::vector::size_type,这是无符号整数类型。这意味着条件i >= 0;始终为true,如果发生overflow,您将获得一些大数字。

  

无符号整数运算总是以2 n 模2执行    其中n是该特定整数中的位数。例如。对于unsigned int,向UINT_MAX添加一个​0,从0减去一个UINT_MAX

答案 1 :(得分:1)

简单复制问题:

#include <iostream>

size_t size()  {return 1;}

int main() {
   for (auto i = size() - 1; i >= 0; --i) {
    std::cout << i << std::endl;
   }
}

size()类型为size_t,文字常量1将提升为size_t,结果auto将变为size_t,但不能小于零,导致i的无限循环和下溢。

答案 2 :(得分:1)

如果您需要反向索引循环,请使用operator -->

当您编写普通索引循环时,可以使用0size<来编写索引循环。

当你编写一个正常的反向索引循环时,事情变得有点不可思议:你需要size - 1>=0,你不能使用 unsigned index,因为无符号i始终为>= 0所以您的支票i >= 0始终返回true,您的循环可以永久运行。

使用伪运算符“转到”,您可以使用0size>来编写反向索引循环,而i无关紧要已签名或未签名:

for (auto i = a.size(); i --> 0; ) //or just i--, or i --> 1, i --> 10...
    std::cout << i << ' ';