We will transform a vector's content by removing items in different ways:
- Let's import all the needed headers and declare that we use the std namespace:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
- A short print helper function will print our vector:
void print(const vector<int> &v)
{
copy(begin(v), end(v), ostream_iterator<int>{cout, ", "});
cout << 'n';
}
- We'll begin with an example vector containing some simple integer values. We'll also print it, so we can see how it changes with the function we apply to it later:
int main()
{
vector<int> v {1, 2, 3, 4, 5, 6};
print(v);
- Now let's remove all the items with the value 2 from the vector. std::remove moves the other items in a way that the one value 2 we actually have in the vector vanishes. Because the vector's actual content is shorter after removing items, std::remove returns us an iterator pointing to the new end. The items between the new end iterator and the old end iterator are to be considered garbage, so we tell the vector to erase them. We surround the two removal lines with a new scope because the new_end iterator is invalidated afterward anyway, so it can go out of scope immediately:
{
const auto new_end (remove(begin(v), end(v), 2));
v.erase(new_end, end(v));
}
print(v);- Now let's remove all the odd numbers. In order to do so, we implement a predicate, which tells us if a number is odd and feed it into the std::remove_if function, which accepts such predicates:
{
auto odd_number ([](int i) { return i % 2 != 0; });
const auto new_end (
remove_if(begin(v), end(v), odd_number));
v.erase(new_end, end(v));
}
print(v);- The next algorithm we try out is std::replace. We use it to overwrite all values of 4 with the value 123. The std::replace function also exists as std::replace_if, which also accepts predicate functions:
replace(begin(v), end(v), 4, 123);
print(v);
- Let's pump completely new values into the vector and create two new empty vectors in order to do another experiment with those:
v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
vector<int> v2;
vector<int> v3;- Then, we implement a predicate for odd numbers again and another predicate function, which tells the opposite if a number is even:
auto odd_number ([](int i) { return i % 2 != 0; });
auto even_number ([](int i) { return i % 2 == 0; });- The next two lines do exactly the same thing. They copy even values to the vectors, v2 and v3. The first line does this with the std::remove_copy_if algorithm, which copies everything from a source container to another container which does not fulfill the predicate constraint. The other line uses std::copy_if, which copies everything that does fulfill the predicate constraint:
remove_copy_if(begin(v), end(v),
back_inserter(v2), odd_number);
copy_if(begin(v), end(v),
back_inserter(v3), even_number);
- Printing both the vectors should now result in the same output:
print(v2);
print(v3);
}
- Let's compile and run the program. The first output line shows the vector after its initialization. The second line shows it after removing all the values of 2. The next line shows the result of removing all the odd numbers. Before the fourth line, we replaced all the values of 4 with 123.
The last two lines show vectors v2 and v3:
$ ./removing_items_from_containers
1, 2, 3, 4, 5, 6,
1, 3, 4, 5, 6,
4, 6,
123, 6,
2, 4, 6, 8, 10,
2, 4, 6, 8, 10,