STL General: How to remove elements of a particular value from a container ?
Q: What is the best way to remove all elements of a particular value from a container?
A: Use the so-called 'remove/erase' idiom:
Code:
// taken from Item 32 of Scott Myers' Effective STL
vector<int> v;
v.erase(remove(v.begin(), v.end(), 99), v.end());
This is because of the simple fact that 'remove()' is a generic algorithm which takes iterators as its arguments. The iterators know nothing of their container; the STL was designed so as to grant the smallest possible amount of coupling. Thus, the iterators cannot call any container's 'erase()' or similar function.
'remove()' DOES return the container's new 'end()' (which just
happens to be the first element that was removed) and this value
can be used in the container's 'erase()' call.
<br><br>
Re: STL General: How to remove elements of a particular value from a container ?
Here is an example of using std::remove_if with a predicate function. The principle is the same as the original post using std::remove. The example is lengthier since I included enough detail for someone to copy, paste, compile the program, and analyze each step with a debugger.
Code:
#include <iostream>
#include <vector>
#include <algorithm>
// predicate function that determines if a value is an odd number.
bool IsOdd (int i) { return ((i%2)==1); }
void remove_if_example()
{
std::vector<int> myints;
for(int i = 0; i < 20; ++i)
{
myints.push_back(i);
}
// remove odd numbers:
std::vector<int>::iterator newEnd =
std::remove_if (myints.begin(), myints.end(), IsOdd);
// print the vector range. It still contains 20 elements! The even
// numbers were copied to the front of the vector while the odd numbers
// were simply overwritten until the entire container has been traversed.
std::cout << "vector contains:";
for (std::vector<int>::iterator p = myints.begin(); p != myints.end(); ++p)
{
std::cout << " " << *p;
}
std::cout << std::endl;
// now erase the elements past the newEnd that was determined
// by std::remove_if
myints.erase(newEnd, myints.end());
// print the range again. Now the vector will only contain the
// even numbers
std::cout << "vector contains:";
for (std::vector<int>::iterator p = myints.begin(); p != myints.end(); ++p)
{
std::cout << " " << *p;
}
std::cout << std::endl;
}
int main ()
{
remove_if_example();
return 0;
}