Say I have a std::vector<int>
with a simple operation to copy those elements which are even:
#include <vector>
int main()
{
std::vector<int> v = {1, 2, 3, 4, 5, 6};
std::vector<int> even;
std::copy_if(std::make_move_iterator(v.begin()), std::make_move_iterator(v.end()), std::back_inserter(even), [](int i){return i%2 == 0;});
return 0;
}
My question how can I combine the above with any other method to remove the elements from vector v
which was copied to vector even
CodePudding user response:
I wouldn't recommend trying to use std::copy_if
here. Instead use std::stable_partition
to move even elements to the end of v
, copy this part to even
using the vector constructor and then erase the copied elements from v
:
int main()
{
std::vector<int> v = { 1, 2, 3, 4, 5, 6 };
// actual logic
auto pivot = std::stable_partition(v.begin(), v.end(), [](int x) { return (x % 2) != 0; });
std::vector<int> even(pivot, v.end());
v.erase(pivot, v.end());
// display results
std::cout << "v:\n";
for (auto x : v)
{
std::cout << x << '\n';
}
std::cout << "even:\n";
for (auto x : even)
{
std::cout << x << '\n';
}
return 0;
}
For objects that are expensive to copy, you may want to use std::move_iterator
when creating even
as suggested in @MooningDucks answer:
std::vector<int> even(std::move_iterator(pivot), std::move_iterator(v.end()));
CodePudding user response:
I would switch to using std::remove_if
instead and have the function you pass to remove_if
do the adding to the other vector. That gives you
std::vector<int> v = {1, 2, 3, 4, 5, 6};
std::vector<int> even;
v.erase(std::remove_if(v.begin(), v.end(),
[&](auto val){ bool cond = (val % 2 == 0);
if (cond) even.push_back(val); return cond; }), v.end());