Using std :: deque :: iterator (in C ++ STL) to find and remove specific elements

I had a problem calling the following code:

#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); } 

resulting in a segmentation error. Having studied the problem, I found that the problem is that the STL controls iterators for deques: if the element to be erased is closer to the end of the deque, the iterator used to indicate the element to be erased will now point to the NEXT element, but not the previous element like vector::iterator . I understand that changing the loop condition from it != deq.end() to it < deq.end() might solve the problem, but I just wonder if there is a way to go through and remove a specific element in deque in "standard form" so that the code can also be compatible with other types of containers.

+4
source share
2 answers

http://en.cppreference.com/w/cpp/container/deque/erase

All iterators and links are invalid [...]

Return value: iterator following the last deleted item.

This is a common pattern when removing items from an STL container inside a loop:

 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 } 

Or as chris mentioned, you can just use std::remove_if .

+18
source

To use erase-remove idiom , you would do something like:

 deq.erase(std::remove_if(deq.begin(), deq.end(), [](int i) { return i%2 == 0; }), deq.end()); 

Be sure to #include <algorithm> make std::remove_if available.

+10
source

All Articles