std :: remove_if无法正常工作

时间:2014-03-29 10:35:40

标签: c++ stl remove-if

这是我的代码。我希望通过成功调用方法'发布'。

从向量中移除所有元素
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如何运作?

4 个答案:

答案 0 :(得分:10)

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());

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

答案 1 :(得分:1)

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

因此,实际上没有从容器中移除任何元素。相反,所有不符合删除标准的元素都以相同的相对顺序汇集到范围的前面。

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

要实际消除容器中的元素,remove应与容器的erase成员函数结合使用(因此名称为“erase-remove idiom”)。

答案 2 :(得分:0)

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

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

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

答案 3 :(得分:0)

请参阅http://en.wikipedia.org/wiki/Erase-remove_idiom

std::remove_if实际上并没有删除擦除元素。它的作用是将满足标准的元素移动到范围的末尾。然后它将迭代器返回到已删除(实际上刚刚移动)元素的第一个元素。然后你可以从容器中删除该范围。

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());