Erase an element in a vector when iterating using swap-and-pop

I want to erase some elements when repeating the vector, but the code below leads to the failure of the statement "iterator is not increasing."

for(auto iter=vec.begin(); iter!=vec.end(); ++iter) { if((*iter).isDead()) { std::swap(*iter, vec.back());//swap with the back vec.pop_back(); //erase the element } } 

What is wrong with this code?

+4
source share
2 answers

You increase the number of elements that you replaced with the current element; and if that was the last element, then you just erased it and invalidated your iterator. You only want to increase if you do not erase using something like:

 for(auto iter=vec.begin(); iter!=vec.end();) { if((*iter).isDead()) { std::swap(*iter, vec.back());//swap with the back vec.pop_back(); //erase the element } else { ++iter; } } 
+7
source

You should increase the iterator only if you do not delete any element in the iteration:

 for(auto iter=vec.begin(); iter!=vec.end();) { if((*iter).isDead()) { std::swap(*iter, vec.back());//swap with the back vec.pop_back(); //erase the element } else ++iter; } 

Or even better, replace the entire loop with remove_if :

 vec.erase(std::remove_if(vec.begin(), vec.end(), std::bind(&ValueType::isDead, _1)), vec.end()); 
+6
source

All Articles