遇到vector.erase()和remove_if()

时间:2015-11-06 16:45:30

标签: c++ vector erase-remove-idiom

在使用remove_if之前,我正在使用remove。所以说如果我有vec = {1,2,2,2,5},并想删除所有2,我会这样做:

for (vector<int>::iterator it = vec.begin(); it!= vector.end(); ++it){
    if (*it == 2){
       vec.erase(remove(vec.begin(),vec.end(), *it), vec.end());
    }
}

这不起作用,因为在删除过程中迭代矢量是不可能和不合逻辑的。

然后我发现了remove_if()。但是,出于某种原因,我不能让它在课程的上下文中工作。这是我的代码:

class SomeClass{
    private:
       vector<int> vec;
    public:
       SomeClass(){
           //initalizae vec to {1,2,2,2,4,5,6,8}
       }
       bool is_even(int value){
           return value % 2 == 0;
       }
       void delete(int a){
           vec.erase(remove_if(vec.begin(), vec.end(), a), vec.end());
       }
       void delete_even(int a){
           vec.erase(remove_if(vec.begin(), vec.end(), this->is_even(a)), vec.end());
       }

我猜无效删除将无效,因为a是一个int,我需要一个bool值,但不知道如何表达&#34;如果int a在此向量中返回true&#34;作为remove_if的第三个参数。我希望void delete_even可以工作,但我得到了

note: in instantiation of function template specialization 'std::__1::remove_if<std::__1::__wrap_iter<int *>, bool>' requested here

2 个答案:

答案 0 :(得分:1)

只需使用std::remove从集合中删除int值,而无需自行搜索:

vec.erase(std::remove(vec.begin(), vec.end(), 2), vec.end());

这将从2中删除所有vec

remove_if的用法是相同的,而不是你提供谓词的元素(通常是函数);如果您可以使用C ++ 11,则可以将其与lambda一起使用:

vec.erase(std::remove_if(vec.begin(), vec.end(), [](int a) {return a % 2 == 0;}), vec.end());

如果要将is_even用作remove_if(或类的其他成员函数)的谓词,那么如评论中所述,您应该将其设置为静态成员函数,最好是。 你也可以bind给非静态成员,但这里没有真正的理由这样做;但如果你很好奇,请参阅Using std::bind with member function, use object pointer or not for this argument?,问题本身包含正确的语法。 is_even静态样本:

 static bool is_even(int value) {
     return value % 2 == 0;
 }

 void delete_even(int a){
     vec.erase(remove_if(vec.begin(), vec.end(), is_even), vec.end());
 }

答案 1 :(得分:1)

如果您只想从向量中删除某些值,则可以使用remove()

foo.erase(std::remove(foo.begin(), foo.end(), some_value), foo.end());

如果你想删除所有偶数,那么我建议使用lambda而不是使用类成员函数。

foo.erase(std::remove_if(foo.begin(), foo.end(), [](auto n) { return n % 2 == 0;}), foo.end());

以下是使用两种方法的示例

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    std::vector<int> foo = {1,2,3,4,5,6,7,8,9};
    // remove all even numbers
    foo.erase(std::remove_if(foo.begin(), foo.end(), [](auto n) { return n % 2 == 0;}), foo.end());
    for (auto e : foo)
        std::cout << e << std::endl;
    std::cout << std::endl;
    // remove all elemenets that match some_value
    foo = {1,2,2,2,2,2,7,8,9};
    int some_value = 2;
    foo.erase(std::remove(foo.begin(), foo.end(), some_value), foo.end());
    for (auto e : foo)
        std::cout << e << std::endl;
}

输出:

1
3
5
7
9

1
7
8
9

Live Example