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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With