Erase from vector without using remove. Is it correct?

I've been told I should use remove-erase to remove multiple occurrences of an element within a vector. However, I prefer doing this:

1
2
3
4
5
6
auto i = vect.begin();
while (i!=vect.end())
   if (*i==someValue)
        i=vect.erase(i);
   else
      ++i;


I know that remove-erase is also available, but would my option be wrong? If so, why? (complexity is not something I'm concerned with right now, so that wouldn't be enough reason for me to switch to remove method).
Thanks.

Edit: I understand that vector capacity is not shrunk unless I explicitly call a resizing method. So I don't see why my iterator would become invalid, if at all.
Last edited on
To the moderators of this forum: it is not a good idea to have two C++ threads - Beginners and General and this question illustrates why - sometimes similar questions are asked on separate threads (see link below). Posters can always overlook previous topics but if these were all in one place at least we'd have a unified starting block and currently there doesn't seem to be any difference in the nature of posts across the 2 threads:

http://www.cplusplus.com/forum/beginner/203059/
Last edited on
Thanks, but I don't see an explicit answer to my question there.
Also, remove-erase allows to remove a specific value from vector, but what if I need to remove only when one field of the vector element matches a certain value? In my code I'd only need to add that field to the if line:
 
if ((*i).field==someValue)


In that case, erase-remove doesn't seem fitting, and also adding unremoved elements to a set is not possible unless I redefine a few operators, which would cause more lines and code becomes messy.
> I know that remove-erase is also available, but would my option be wrong?
> complexity is not something I'm concerned with right now

The erase-remove idiom still has the advantage of clarity and transparency.

This one-liner is idiomatic: every C++ programmer (who has programmed professionally) would immediately understand what is being done.
vect.erase( std::remove( vect.begin(), vect.end(), some_value ), vect.end() ) ;

In contrast, this is not as easy to comprehend: to understand what is being done, first one needs to understand how it is being done.
1
2
3
4
5
6
auto i = vect.begin();
while (i!=vect.end())
   if (*i==someValue)
        i=vect.erase(i);
   else
      ++i;



> Also, remove-erase allows to remove a specific value from vector,
> but what if I need to remove only when one field of the vector element matches a certain value?

std::remove_if: http://en.cppreference.com/w/cpp/algorithm/remove

1
2
const auto if_eq = [some_value] ( const auto& item ) { return item.field == some_value ; } ;
vect.erase( std::remove_if( vect.begin(), vect.end(), if_eq ), vect.end() ) ;



> adding unremoved elements to a set

1
2
3
const auto iter = std::remove_if( vect.begin(), vect.end(), [some_value] ( const auto& item ) { return item.field == some_value ; } ) ;
my_set.insert( vect.begin(), iter ) ;
vect.erase( iter, vect.end() ) ;
Last edited on
closed account (48T7M4Gy)
Another good explanation I can find is at:
https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom

The bottom line is the STL containers do the work for you even though a 'manual' loop is just as good, all things equal.

Interestingly, in the light of the wikipedia article, because of the j-- in the solution I posted on the other thread and gunnerfunners comment about duplicate posting this is definitely a case where the OP question is better illuminated on the first thread.

Neither approach is strictly better than the other. It depends where you stand with knowledge, clarity, convenience and the need for efficiency and robustness. There's nothing wrong with being across both.
Thanks for the enlightening :)
Topic archived. No new replies allowed.