矢量大小自动失败

Auto failed for vector size

我正在尝试使用 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;
}

当使用 auto 时,i 的类型会是 std::vector::size_type, which is an unsigned integer type. That means the condition i >= 0; would be always true, and if overflow,你会得到一些大数字。

Unsigned integer arithmetic is always performed modulo 2n where n is the number of bits in that particular integer. E.g. for unsigned int, adding one to UINT_MAX gives ​0​, and subtracting one from ​0​ gives UINT_MAX.

问题的简单再现:

#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,不能小于0,导致i的无限循环和下溢。

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

当你写一个普通的索引循环时,你用0size<来写。

当你编写一个正常的反向索引循环时,事情变得有点不稳定:你需要 size - 1>=0,而你不能使用 unsigned 索引,因为 unsigned i 总是 >= 0 所以你的检查 i >= 0 总是 returns true,你的循环可以 运行 永远。

有了fake运算符"goes to",可以用0size>来写反向索引循环,如果i 是有符号还是无符号:

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