If for instance you have a std::vector<MyClass>
, where MyClass
has a public method: bool isTiredOfLife()
, how do you remove the elements that return true?
vector::erase() erase() function is used to remove elements from a container from the specified position or range.
If you need to remove multiple elements from the vector, the std::remove will copy each, not removed element only once to its final location, while the vector::erase approach would move all of the elements from the position to the end multiple times. For Example, Consider removing all elements < 5 in following vector.
I prefer remove_if
v.erase(remove_if(v.begin(), v.end(),
mem_fun_ref(&MyClass::isTiredOfLife)),
v.end());
remove_if
returns an iterator pointing after the last element that's still in the sequence. erase
erases everything from its first to its last argument (both iterators).
Using remove_if is the "right" way to do this. Be careful NOT to use an iterator to cycle through and erase, because removing items invalidates the iterator. In fact, any example which uses erase() as its primary method is a bad idea on vectors, because erase is O(n), which will make your algorithm O(n^2). This should be an O(n) algorithm.
The method I give below is likely to be faster than remove_if but, unlike remove_if, will NOT preserve the relative order of the elements. If you care about maintaining order (i.e. your vector is sorted), use remove_if, as in the answer above. If you don't care about order, and if the number of items to be deleted is typically less than a quarter of the vector, this method is likely to be faster:
for( size_t i = 0; i < vec.size(); )
if( vec[i].isTiredOfLife() )
{
vec[i] = vec.back();
vec.pop_back();
}
else
++i;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With