如果我在 for
循环中使用 iterator
并且在迭代器的当前迭代中使用 erase
,则 for 循环应该继续正常并访问其余的 list
元素?
根据我的阅读,这应该是这种情况,并且是 list
与 deque
或 vector
的主要区别特征。就我而言,queue
可能有效,但我需要这种行为。
这是我正在考虑的循环:
std::list<Sequence>::iterator iterator;
iterator=m_concurrents.begin();
for (;iterator!=m_concurrents.end();++iterator){
if (iterator->passes()){
m_concurrents.erase(iterator);
}
}
最佳答案
编写该循环的惯用方法是:
for (auto i = list.begin(); i != list.end();) {
if (condition)
i = list.erase(i);
else
++i;
}
您可以对 set
、multiset
、map
或 multimap
执行相同的操作。对于这些容器,您可以删除一个元素而不影响任何迭代器对其他元素的有效性。其他容器,如 vector
或 deque
就不是那么友好了。对于那些容器,只有被删除的迭代器之前的元素保持不变。这种差异仅仅是因为 list
将元素存储在单独分配的节点中。很容易取出一个链接。 vector
是连续的,取出一个元素会将其后的所有元素移回一个位置。
您的循环中断是因为您在某些给定条件下删除了 i
处的元素。 i
在该调用之后不再是有效的迭代器。您的 for
循环然后递增 i
,但 i
无效。人间 hell 随之而来。这就是为什么 erase
将迭代器返回到被删除后的元素的确切情况...这样您就可以继续遍历 list
。
你也可以使用 list::remove_if
:
list.remove_if([](auto& i) { return i > 10; });
在 lambda 中,如果应该删除该元素,则返回 true。在此示例中,它将删除所有大于 10 的元素。
关于c++ - 在迭代 std::list 时删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40327383/