繁体   English   中英

是否有更好的替代std :: remove_if来从向量中删除元素?

[英]Is there a better alternative to std::remove_if to remove elements from a vector?

std::vector或其他容器中删除具有特定属性的元素的任务使其自身具有功能样式实现:为什么要烦恼循环,内存释放和正确移动数据?

但是,在C ++中执行此操作的标准方法似乎是以下习惯用法:

std::vector<int> ints;
...
ints.erase(
    std::remove_if(ints.begin(), 
                   ints.end(),
                   [](int x){return x < 0;}),
    ints.end());

此示例从整数向量中删除小于零的所有元素。

我发现它不仅丑陋而且容易错误使用。 很明显, std::remove_if不能改变向量的大小(正如其名称所暗示的那样),因为它只传递迭代器。 但是许多开发人员,包括我自己,在开始时都没有这样做。

那么有更安全,更有希望实现这一目标的方式吗? 如果没有,为什么?

我发现它不仅丑陋而且容易错误使用。

别担心,我们都在一开始就做了。

很明显,std :: remove_if不能改变向量的大小(正如其名称所暗示的那样),因为它只传递迭代器。 但是许多开发人员,包括我自己,在开始时都没有这样做。

相同。 它让每个人感到困惑。 这些年前可能不应该被称为remove_if 后见之明,是吗?

那么有更安全,更有希望实现这一目标的方式吗?

没有

如果没有,为什么?

因为这是从容器中删除项目时保留性能的最安全,最优雅的方法,其中删除项目使迭代器无效。

预测:

我能做什么?

是的,将这个成语包装成一个函数

template<class Container, class F>
auto erase_where(Container& c, F&& f)
{
    return c.erase(std::remove_if(c.begin(), 
                                  c.end(),
                                  std::forward<F>(f)),
                   c.end());    
}

然后,激励示例中的调用变为:

auto is_negative = [](int x){return x < 0;};
erase_where(ints, is_negative);

要么

erase_where(ints, [](int x){return x < 0;});

通过std::experimental::erase_if算法很快就可以在C ++ 17就绪编译器中使用它:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
#include <experimental/vector>

int main()
{
    std::vector<int> ints { -1, 0, 1 };   
    std::experimental::erase_if(ints, [](int x){
        return x < 0;
    });
    std::copy(ints.begin(), ints.end(), std::ostream_iterator<int>(std::cout, ","));
}

打印0,1的实例

暂无
暂无

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

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