In-place std::copy_if

c++, c++11, stl

Solution

`copy_if` is primarily for copying a range to another range/container I.e. by design, the nature of the algorithm is to copy the elements satisfying some condition to another (non-overlapping) range or to a new container.

`remove_if` is more appropriate for what you need; it is exactly for filtering out as you expect. However, it only removes the elements by overwriting; the remnants between the old and new ends would be unspecified elements after the function's completion and needs to be manually erased using `erase`, like so:

std::vector<int> vec { 1, 2, 3, 4 };
vec.erase(std::remove_if(std::begin(vec),
                         std::end(vec),
                         [](int i) { return i <= 2; }),
          std::end(vec));

This is a C++ idiom that goes by the name erase-remove.

Instead of `copy_if`, if `copy` was what you wanted, then you've an alternative for overlapping ranges, namely `copy_backward`; from the documentation

If d_first is within [first, last), std::copy_backward must be used instead of std::copy.

Problem

It appears to me that `std::copy_if` would be very useful for filtering containers: ``` std::vector<int> vec { 1, 2, 3, 4 }; auto itEnd = std::copy_if(vec.begin(), vec.end(), vec.begin(), [](int i) { return i > 2; }); vec.resize(itEnd - vec.begin()); ``` However, `std::copy_if` is specified that the input and output ranges may not overlap. Is there an alternative?

Original source