No it doesn't. There's functions that do one (remove elements which match a predicate) or the other (copy elements which match a predicate) but not both. But it's easy enough to write our own in two steps:
template <typename InputIter, typename OutputIter, typename UnaryPredicate>
InputIter remove_and_copy(InputIter first, InputIter last,
OutputIter d_first, UnaryPredicate pred)
{
std::copy_if(first, last, d_first, pred);
return std::remove_if(first, last, pred);
}
To be used like:
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7};
std::vector<int> u;
v.erase(
remove_and_copy(v.begin(), v.end(), std::back_inserter(u),
[](int i) { return i%2 == 0; }),
v.end()
);
// now v is {1, 3, 5, 7} and u is {2, 4, 6}
If you only need vector
you can write it a bit differently, but still just 2 lines:
template <typename T, typename UnaryPredicate>
void remove_and_copy(std::vector<T>& from, std::vector<T>& to, UnaryPredicate pred)
{
std::copy_if(from.begin(), from.end(), std::back_inserter(to), pred);
from.erase(std::remove_if(from.begin(), from.end(), pred), from.end());
}
Or write your own loop:
template <typename T, typename UnaryPredicate>
void remove_and_copy(std::vector<T>& from, std::vector<T>& to, UnaryPredicate pred)
{
for (auto it = from.begin(); it != from.end(); ) {
if (pred(*it)) {
to.push_back(*it);
it = from.erase(it);
}
else {
++it;
}
}
}
Usage of either:
remove_and_copy(v, u, [](int i) { return i%2 == 0; });