Cleanly removing elements from an std::vector
I'm having trouble figuring out a way to cleanly and efficiently remove elements from a vector. What I'm doing is iterating through a vector, and during the loop, elements may need to be removed, or they may not, and the vector is not sorted. I need to remove the unwanted elements from the middle of the vector, hopefully without stopping looping. When I tried vector.erase(iterator), the program threw a segfault, which I kind of expected :( If I need to do something like loop through the vector backwards and remove values that way, how would I do that? I found a bunch of other kind of iterators, like the reverse_iterator, but I don't understand how to use them.
Any tips? Thanks. I would just like the easiest to understand (primarily), and most efficient (secondarily) way to do this.
Yeah, the solution is a bit dirty-looking, but it works:
The direction you iterate in doesn't matter, since the key issue is that the current iterator is invalidated no matter what.
for(it = myVec.begin(); it != myVec.end();){ if(NeedsRemoval(*it)) it = erase(it); else ++it;}
The direction you iterate in doesn't matter, since the key issue is that the current iterator is invalidated no matter what.
Since your elements are not sorted, how about something like this:
You may remove duplicate elements in the same loop without invalidating the iterator also.
MyVec::iterator It (myVec.begin ()) ;MyVec::size_type NElems = myVec.size () ;MyVec::size_type Counter = 0 ;while (Counter != NElems){ //If current element need to be removed if (NeedsRemoval (*It)) { (*It) = myVec.back () ; //Save the last element to the current //removing element, to ensure there's no //'hole' in the array m_Vec.pop_back () ; //The last element is saved, we may remove //it by now if (Counter != (NElems - 1)) --NElems ; //NElems is now decreased by 1, be careful //with this, if we don't have the if //statement, !this is a bug! } ++It ; ++Counter ;}
You may remove duplicate elements in the same loop without invalidating the iterator also.
Quote:Original post by Zipster
for(it = myVec.begin(); it != myVec.end();)
{
if(NeedsRemoval(*it))
it = erase(it);
else
++it;
}
#include <algorithm>myVec.erase( std:remove_if( myVec.begin(),myVec.end(), &NeedsRemoval), myVec.end() );
EDIT: forgot a comma
[Edited by - rip-off on January 28, 2006 5:02:11 AM]
Quote:Original post by rip-off#include <algorithm>myVec.erase( std:remove_if( myVec.begin(),myVec.end(), &NeedsRemoval) myVec.end() );
We have a winner.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement