【问题标题】:std::remove_if not working properly [duplicate]std::remove_if 无法正常工作[重复]
【发布时间】:2014-05-08 22:08:48
【问题描述】:

这是我的代码。我想从向量中删除所有成功调用方法“释放”的元素。

bool foo::release()
{
    return true;
}

// ...
vector<foo> vec;
// ...
remove_if(vec.begin(), vec.end(), [](foo & f) { return f.release() == true; });
// ...

但是remove_if 没有从vector vec 中删除所有元素。 remove_if 是如何工作的?

【问题讨论】:

    标签: c++ stl remove-if


    【解决方案1】:

    因为remove_if 算法对由两个前向迭代器表示的一系列元素进行操作,所以它不知道底层容器或集合。

    因此,实际上没有从容器中删除任何元素。相反,所有不符合删除条件的元素都以相同的相对顺序一起放在范围的前面。

    其余元素处于有效但未指定的状态。完成此操作后,remove 返回一个迭代器,该迭代器指向最后一个未删除元素之后的一个元素。

    要真正从容器中删除元素,remove 应该与容器的erase 成员函数结合使用(因此得名“erase-remove idiom”)。

    【讨论】:

      【解决方案2】:

      std::remove_if 重新排列向量的元素,使您想要保留的元素在[vec.begin(), return_iterator) 范围内(注意部分开放范围)。因此,您需要调用std::vector::erase 以确保向量仅包含所需的元素。这被称为erase-remove idiom

      auto it = remove_if(vec.begin(),
                          vec.end(),
                          [](foo & f) { return f.release() == true; });
      
      vec.erase(it, vec.end());
      

      在这里,为了清楚起见,我将它分成两行,但它通常被视为单行。

      【讨论】:

      • 谢谢,它工作得很好,看起来还不错。
      【解决方案3】:

      std::removestd::remove_if 实际上并没有删除任何东西,只是给你一个迭代器,然后你可以使用你使用的任何容器的适当成员函数删除元素。在std::vector 的情况下,erase

      我邀请您阅读 Scott Meyers 的这篇旧文章:"My Most Important C++ Aha! Moments...Ever"

      因此,我怀着相当的震惊和背叛的感觉,发现对容器应用 remove 永远不会改变容器中元素的数量,即使你要求它删除所有内容也不行。欺诈罪!欺骗!虚假广告!

      【讨论】:

        【解决方案4】:

        http://en.wikipedia.org/wiki/Erase-remove_idiom

        std::remove_if 实际上并没有obliterate 擦除元素。它所做的是将满足条件的元素移动到范围的末尾。然后它返回一个迭代器,指向已删除(实际上只是移动)元素的第一个元素。然后,您可以从容器中删除该范围。

        vector<foo> vec;
        auto remove_start = remove_if(vec.begin(), vec.end(), [](foo & f) { return f.release() == true; });
        
        vec.erase(remove_start, vec.end());
        

        vec.erase(remove_if(vec.begin(), vec.end(),
                            [](foo & f) { return f.release() == true; }),
                  vec.end());
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-05-19
          • 1970-01-01
          • 1970-01-01
          • 2017-07-15
          • 2015-09-06
          • 2016-05-06
          • 2016-05-12
          • 2018-07-19
          相关资源
          最近更新 更多