for (auto it = testcont.rbegin(), nit = it; it != testcont.rend(); it = nit) {
nit = next(it);
// whatever... maybe a continue somewhere or maybe not
if (WE_WANT_TO_ERASE(it)) {
nit = decltype(it){ testcont.erase(std::next(it).base()) };
}
// whatever... maybe a continue somewhere or maybe not
}
2条答案
按热度按时间syqv5f0l1#
erase
使迭代器无效,所以你必须从erase
的返回值重新构造它:C++11:
C++17:
Demo。
为了完整起见,下面是从原始问题中更正的循环的样子(注意迭代器增量已从
for(...)
中删除):csga3l582#
在使用了这个习惯用法之后,我认为对Jarod42的答案中的循环进行修改是为了使事情更安全并保持典型的
for(;;)
循环细节:在其他答案中使用循环太危险了。如果在循环中的某个地方轻率地添加一个
continue;
,而没有先递增迭代器,结果将是一个无限循环。因为,乍一看,这看起来像一个普通的for(;;)
循环,我相信这迟早会发生。类似地,如果循环中有分支,并且其中一个分支忽略了递增迭代器,则会引入另一个错误。最后,如果你做了一个erase()
,你需要在递增迭代器之前确保continue
,否则你会有另一个bug。使用上面修改过的循环,该循环可以像普通的
for(;;)
循环一样处理。技巧是在循环体的第一行增加nit
(“下一个迭代器”)。那你就不用担心了您需要更新nit
的唯一时间是如果您正在执行erase()
。其他一切都像人们期望的for循环一样工作。最后一点:我最初问的是关于Map的问题,但这也适用于
vector
,list
等。