如果我iterator
在for
循环中使用an 并且erase
在迭代器的当前迭代中使用,for循环应该继续正常并访问其余list
元素?
从我所读到的,这应该是这种情况,并且是list
vs 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);
}
}
Run Code Online (Sandbox Code Playgroud)
Dav*_*vid 48
编写该循环的惯用方法是:
for (auto i = list.begin(); i != list.end();) {
if (condition)
i = list.erase(i);
else
++i;
}
Run Code Online (Sandbox Code Playgroud)
你可以做同样的事情了set
,multiset
,map
,或multimap
.对于这些容器,您可以擦除元素,而不会影响对其他元素的任何迭代器的有效性.其他容器喜欢vector
或deque
不那么友善.对于那些容器,只有擦除迭代器之前的元素保持不变.这种差异仅仅是因为list
s存储元素在单独分配的节点中.一个链接很容易.vector
s是连续的,取出一个元素后,将所有元素移回一个位置.
您的循环被破坏,因为您i
在某些给定条件下擦除了元素.i
在该调用之后不再是有效的迭代器.for
然后你的循环递增i
,但i
无效.地狱般的地狱随之而来.这就是为什么erase
在删除之后将迭代器返回到元素的确切情况...所以你可以继续遍历list
.
你也可以使用list::remove_if
:
list.remove_if([](auto& i) { return i > 10; });
Run Code Online (Sandbox Code Playgroud)
在lambda中,如果要删除元素,则返回true.在此示例中,它将删除大于10的所有元素.