std::vector<T>::erase()

Started by
3 comments, last by Wavarian 20 years, 4 months ago
Just a quick question this time, since the erase() method invalidates the iterator passed, is the following safe?

std::vector<int> vlist;
std::vector<int>::iterator itr;

// Add int elements here


// remove every element == 0

for(itr = vlist.begin(); itr != vlist.end(); itr++)
   if((*itr) == 0){
      itr--;
      vlist.erase(itr + 1);
   }

edit: removed some junk so to lessen the confusion [edited by - wavarian on November 27, 2003 10:32:32 PM]
Advertisement
For vector<> that's not OK; all iterators are invalidated. For list<> you only invalidate the item pointed at.

However, most people use the semantic of the post-increment to do the same thing.

std::list<> the_list;while( iter != the_list.end() ) {  if( SHOULD_DELETE( *iter ) ) {    the_list.erase( iter++ );  }  else {    ++iter;  }}  


The problem with your approach is that it fails when you want to delete the first item (as you try to -- on begin()).

[edited by - hplus0603 on November 27, 2003 11:24:55 PM]
enum Bool { True, False, FileNotFound };
std::vector::erase returns an iterator to the next element, IIRC.
vector::erase() returns an iterator pointing to the value just passed the value erased, so instead of doing the iterator increment/decrement dance, try something like:
for(itr = vlist.begin(); itr != vlist.end(); ) {   if((*itr) == 0){      itr = vlist.erase(itr);  // effectively increments the iterator   } else {      itr++;   }}  


However, worrying about invalidated iterators is generally bad news. Consider using std::remove() or std::remove_if() instead. i.e.:
vlist.erase(std::remove(vlist.begin(),                        vlist.end(),                        0),            vlist.end());  

Fewer worries about invalidated iterators, and more efficient to boot.

edit: !@#$! smilies

[edited by - SiCrane on November 27, 2003 11:04:47 PM]
Interesting points, I had tried using the return value of erase() within the loop, but for some strange reason I got a runtime error.

I''ll have to look into it again. And yeah my method is clearly not safe as someone had pointed out with my backtracking method.

And I think your method of using std::remove() looks pretty sweet SiCrane, just might do the trick

Cheers again guys, I''m just one step closer to understanding how to properly use STL.

This topic is closed to new replies.

Advertisement