There are two versions of remove (without copy) algorithms. They are
template<class ForwardIterator, class T>
ForwardIterator remove(ForwardIterator first, ForwardIterator last,
const T& value);
and
template<class ForwardIterator, class Predicate>
ForwardIterator remove_if(ForwardIterator first, ForwardIterator last,
Predicate pred);
The first variant of the algorithm "removes" all elements in a container that satisfy the condition *i == value
where i
is an iterator in the range [first, last)
.
The second variant of the algorithm "removes" all elements in a container that satisfy the condition pred(*i) != false
where i
is an iterator in the range [first, last)
.
In fact the predicate is used in an if statement and its value contextually is converted to the type bool.
The algorithms do not actually remove elements. They move them to the end of the range and return the end of the resulting range that is of the range of actual elements after moving "removed" elements.
Calling the member function erase
results in actual removing these elements.
Consider the following demonstrative program.
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
auto last = std::remove_if( v.begin(), v.end(), []( int x ) { return x % 2; } );
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;
for ( auto first = v.begin(); first != last; ++first )
{
std::cout << *first << ' ';
}
std::cout << "||| ";
for ( auto first = last; first != v.end(); ++first )
{
std::cout << *first << ' ';
}
std::cout << std::endl;
v.erase( last, v.end() );
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;
return 0;
}
Its output is
0 2 4 6 8 5 6 7 8 9
0 2 4 6 8 ||| 5 6 7 8 9
0 2 4 6 8