这是我的代码。我希望通过成功调用方法'发布'。
从向量中移除所有元素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
如何运作?
答案 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::remove
和std::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());