简体   繁体   English

如何通过处理元素和从原始容器中删除这些元素来使用 std::copy_if

[英]How do I use std::copy_if by both coping elements and removing those elements from the original container

Say I have a std::vector<int> with a simple operation to copy those elements which are even:假设我有一个std::vector<int>有一个简单的操作来复制那些偶数的元素:

#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我的问题是如何将上述方法与任何其他方法结合起来,从 vector v中删除被复制到 vector even的元素

I wouldn't recommend trying to use std::copy_if here.我不建议在这里尝试使用std::copy_if 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 :而是使用std::stable_partition将 even 元素移动到v的末尾,使用 vector 构造函数将这部分复制到even ,然后从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::move_iteratoreven按照@MooningDucks 回答中的建议:

std::vector<int> even(std::move_iterator(pivot), std::move_iterator(v.end()));

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.我会改为使用std::remove_if并让传递给remove_if的函数执行添加到另一个向量的操作。 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());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM