我写了这个简单的测试程序。但我不明白这里发生了什么。因为输出中有一个奇怪的东西:
std::list<std::pair<double,double>> l;
l.push_back({0.3,0.9});
l.push_back({-0.3,0.5});
l.push_back({0.3,0.7});
l.push_back({1.2,1.83});
for(auto it=l.begin(); it!=l.end(); ++it){
double lx= it->first + 0.01;
double ly= it->second + 0.01;
it->first = lx;
it->second = ly;
if(lx < 0.0 || lx > 1.0 || ly < 0.0 || ly > 1.0){
it = l.erase(it);
}
如果我打印列表,我得到:
0.32, 0.92
0.31, 0.71
为什么迭代器返回到第一个元素(两次+0.1)?
最佳答案
it=list.erase(it);
这会删除 it
处的元素。然后返回被删除元素之后的迭代器位置。
当您的 for
循环完成一次迭代时,它会通过 ++
推进 it
然后检查它是否等于 end()
。
所以你的循环在每个元素被删除后都会跳过该元素。不好。如果它删除最后一个元素,它会继续前进到结束迭代器,这是非法的。
从 for
循环 header 中删除 ++it
。在循环的底部,要么推进 it
要么 在 it
处删除,既不能同时也不能两者都不。
奇怪的打印行为是由于 UB。在位置 0 增加数据。在位置 1 增加数据,然后删除它。您跳过位置 2。您在位置 3 增加数据,然后删除它。您前进到结束迭代器(未定义的行为)。然后随机的事情发生,恰好再次增加数据位置 0 和 2。作为猜测,结束迭代器上的 ++
恰好循环回到您的特定情况下的第一个元素(这根本不能保证,但使用 UB 任何事情都可能发生)。然后第二个循环正常运行,增加两个元素的数据并且不删除任何内容。
关于c++ - 当一个列表元素被删除时,迭代器最后会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40917794/