我在调用以下代码时遇到问题:
#include<deque>
using namespace std;
deque<int> deq = {0,1,2,3,4,5,6,7,8};
for(auto it = deq.begin(); it != deq.end(); it++){
if(*it%2 == 0)
deq.erase(it);
}
导致分段错误。在查看问题后,我发现问题在于STL管理deques的迭代器的方式:如果被擦除的元素更接近deque的末尾,用于指向擦除元素的迭代器现在将指向NEXT元素,但不是vector::iterator
之前的元素。我知道将循环条件从it != deq.end()
修改为it < deq.end()
可能会解决问题,但我只是想知道是否有办法遍历&amp;在“标准格式”中删除双端队列中的某些元素,以便代码也可以与其他容器类型兼容。
答案 0 :(得分:18)
http://en.cppreference.com/w/cpp/container/deque/erase
所有迭代器和引用都无效[...]
返回值:最后一个删除元素后的迭代器。
这是从循环内的STL容器中删除元素时的常见模式:
for (auto i = c.begin(); i != c.end() ; /*NOTE: no incrementation of the iterator here*/) {
if (condition)
i = c.erase(i); // erase returns the next iterator
else
++i; // otherwise increment it by yourself
}
或者如chris所述,您可以使用std::remove_if
。
答案 1 :(得分:10)
要使用erase-remove idiom,您可以执行以下操作:
deq.erase(std::remove_if(deq.begin(),
deq.end(),
[](int i) { return i%2 == 0; }),
deq.end());
请务必#include <algorithm>
使std::remove_if
可用。