[英]having trouble with vector.erase() and remove_if()
在使用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且我需要一个布尔值,但不确定如何将“如果int a在此向量中返回true”表示为remove_if的第三个参数。 而且我希望void delete_even可以正常工作,但是我得到了
note: in instantiation of function template specialization 'std::__1::remove_if<std::__1::__wrap_iter<int *>, bool>' requested here
只需使用std::remove
从集合中删除一个int
值,而无需自己搜索:
vec.erase(std::remove(vec.begin(), vec.end(), 2), vec.end());
这将从vec
删除所有出现的2
。
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
到非静态成员,但是这里没有真正的理由; 但是请参阅将std :: bind与成员函数结合使用,是否为此参数使用对象指针? 如果您感到好奇,则问题本身包含正确的语法。 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());
}
如果您只想从向量中删除一些值,则可以使用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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.