在迭代C ++向量时从C ++向量中删除元素的正确方法是什么?我正在迭代一个数组,并希望删除一些符合特定条件的元素。我被告知在遍历期间修改它是一件坏事。
我想我还应该提一下,这是一个指针数组,我需要在删除之前释放它们。
编辑:
所以这是我的代码片段。
void RoutingProtocolImpl::removeAllInfinity()
{
dv.erase(std::remove_if(dv.begin(), dv.end(), hasInfCost), dv.end());
}
bool RoutingProtocolImpl::hasInfCost(RoutingProtocolImpl::dv_entry *entry)
{
if (entry->link_cost == INFINITY_COST)
{
free(entry);
return true;
}
else
{
return false;
}
}
编译时出现以下错误:
RoutingProtocolImpl.cc:368: error: argument of type bool (RoutingProtocolImpl::)(RoutingProtocolImpl::dv_entry*)' does not match
bool (RoutingProtocolImpl::)(RoutingProtocolImpl::dv_entry)'
抱歉,我有点像C ++ newb。
答案 0 :(得分:20)
vector erase()
方法返回一个可用于继续迭代的新迭代器:
std::vecor<MyClass> v = ...;
std::vecor<MyClass>::iterator it = v.begin();
while (it != v.end()) {
if (some_condition(*it)) {
it->cleanup(); // or something
it = v.erase(it);
}
else {
++it;
}
}
答案 1 :(得分:13)
bool IsEven (int i)
{
return (i%2) == 0;
}
//...
std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.erase(std::remove_if(v.begin(),v.end(),IsEven), v.end());
//v now contains 1 and 3
答案 2 :(得分:5)
与Brian R. Bondy的答案相同,但我使用的是仿函数而不是函数 指针,因为编译器更擅长内联它们:
struct IsEven : public std::unary_function<int, bool>
{
bool operator()(int i)
{
return (i%2) == 0;
};
}
//...
std::erase(std::remove_if(v.begin(),v.end(),IsEven()), v.end());
编辑:回应
如果我的向量是指针需要在删除后释放,我该怎么做?
struct IsEven : public std::unary_function<int, bool>
{
bool operator()(int i)
{
return (i%2) == 0;
};
}
struct DeletePointer : public std::unary_function<myPointedType *, void>
{
void operator()(myPointedType * toDelete)
{
delete toDelete;
};
}
//...
typedef std::vector<something>::iterator Iterator_T;
Iterator_t splitPoint = std::partition(v.begin(),v.end(),IsEven());
std::for_each(v.begin(), splitPoint, DeletePointer());
v.erase(v.begin(), splitPoint);