矢量大小自动失败
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 -->
当你写一个普通的索引循环时,你用0
、size
和<
来写。
当你编写一个正常的反向索引循环时,事情变得有点不稳定:你需要 size - 1
、>=
、0
,而你不能使用 unsigned 索引,因为 unsigned i
总是 >= 0
所以你的检查 i >= 0
总是 returns true
,你的循环可以 运行 永远。
有了fake运算符"goes to",可以用0
、size
、>
来写反向索引循环,如果i
是有符号还是无符号:
for (auto i = a.size(); i --> 0; ) //or just i--, or i --> 1, i --> 10...
std::cout << i << ' ';
我正在尝试使用 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 toUINT_MAX
gives0
, and subtracting one from 0
givesUINT_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 -->
当你写一个普通的索引循环时,你用0
、size
和<
来写。
当你编写一个正常的反向索引循环时,事情变得有点不稳定:你需要 size - 1
、>=
、0
,而你不能使用 unsigned 索引,因为 unsigned i
总是 >= 0
所以你的检查 i >= 0
总是 returns true
,你的循环可以 运行 永远。
有了fake运算符"goes to",可以用0
、size
、>
来写反向索引循环,如果i
是有符号还是无符号:
for (auto i = a.size(); i --> 0; ) //or just i--, or i --> 1, i --> 10...
std::cout << i << ' ';