【问题标题】:Usage of predicate function in std::remove_ifstd::remove_if 中谓词函数的使用
【发布时间】:2013-04-11 02:31:25
【问题描述】:

我有一个对象向量。我的数据结构如下:

 class my_class{
       float a; int b;
 };
 my_class obj;
 vector<my_class> vec;

向量 vec 包含以下形式的数据:

 vec
 ((10.0,2),(100,3),(19.0,3)...)

现在,我打算从向量 vec 中删除小于或等于 vec 的最后一个元素的元素...为此,我使用了擦除和 remove_if 函数:

vec.erase(std::remove_if(vec.begin(), vec.end(), predicate_function(vec, (vec.end()-1).a, (vec.end()-1).b)), vec.end());

我拥有的 predicate_function 对“vec”进行了迭代。然而,这违背了使用 std::remove_if 的目的。有人可以帮忙看看 predicate_function 应该是什么样子才能使 remove_if 工作。我不想使用 lambda_function。我的编译器也是 GCC

【问题讨论】:

    标签: c++


    【解决方案1】:

    谓词函数将自动从每个迭代器传递参数。所以它看起来像:

    bool predicate_function(const my_class& m)
    {
        //Some logic here
    }
    

    然后简单地称为:

    vec.erase(std::remove_if(vec.begin(), vec.end(), predicate_function), vec.end());
    

    在 C++ 术语中,std::remove_if 期望 UnaryPredicate 作为其第三个参数,它是接受 1 个参数并返回 bool 的函数或仿函数。

    编辑:要在评论中做你想做的事,你需要使用functor(或std::bind,但我们会在这里走仿函数路线):

    struct compare_last
    {
        const my_class last_;
    
        compare_last(const my_class& last)
          : last_(last)
        { }
    
        bool operator()(const my_class& m) const
        {
            return m == last_; //Or however you do your comparisons
        }
    };
    
    my_class& last = *(--vec.end());
    vec.erase(std::remove_if(vec.begin(), vec.end(), compare_last(last)), vec.end());
    

    【讨论】:

    • 现在在 predicate_function 内部,我将如何与向量的最后一个对象进行比较...因为谓词对象只传递了一个迭代器的参数。 PS:谢谢回复
    • 您不认为remove_if() 删除了需要删除的内容吗?你为什么保留vec.erase()?不仅如此,vec.end() 可能会在您将其作为erase() 的最后一个参数调用的时间和remove_if() 返回的时间之间发生变化。
    • @AlexisWilke No, it doesn't。这是一个著名的 C++ 习惯用法:erase-remove idiom。 vec.end() 实际上可以改变的唯一方法是,如果在多线程环境中没有同步访问它。
    猜你喜欢
    • 2017-03-01
    • 1970-01-01
    • 2017-12-11
    • 1970-01-01
    • 2016-12-14
    • 1970-01-01
    • 2011-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多