我正在尝试使用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;
}
答案 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 -->
当您编写普通索引循环时,可以使用0
,size
和<
来编写索引循环。
当你编写一个正常的反向索引循环时,事情变得有点不可思议:你需要size - 1
,>=
,0
,你不能使用 unsigned index,因为无符号i
始终为>= 0
所以您的支票i >= 0
始终返回true
,您的循环可以永久运行。
使用伪运算符“转到”,您可以使用0
,size
和>
来编写反向索引循环,而i
无关紧要已签名或未签名:
for (auto i = a.size(); i --> 0; ) //or just i--, or i --> 1, i --> 10...
std::cout << i << ' ';