在for循环内调用函数以删除向量(或列表)中的元素

时间:2019-12-03 19:00:50

标签: c++ class vector memory-management erase-remove-idiom

vector<node>::iterator it;
for(it;it!=vector_of_node.end();it++){
    if(it->get_name()=="MARIA"){
        vector_of_node.erase(it);
}

我希望我的代码目标明确。我想从向量(在这种情况下为vector_of_nodes)中消除多个对象(在称为节点的类中进行了描述)。 当我运行我的代码时,编译器没有收到任何错误,但运行时却失败了。我确定错误是在我共享的这部分代码上。你能帮我吗?

2 个答案:

答案 0 :(得分:1)

使用您当前的方法,即,一次擦除向量中的元素,被擦除的元素之后的所有元素都必须移到向量的 front 处。每次删除元素的迭代都会执行此操作(仅当删除向量的 back 时元素才会移动)。

作为替代方案,您可能需要考虑使用Erase-remove idiom。如果您打算从std::vector中删除多个元素,则更合适。

// predicate (C++14 for generic lambda)
auto is_maria = [](auto elem) {
   return elem.get_name() == "MARIA";
};  

auto end = std::remove_if(vector_of_node.begin(), vector_of_node.end(), is_maria); 
vector_of_node.erase(end, vector_of_node.end());

这个想法是将要擦除的元素留在向量的后面,然后通过一次erase()调用从相应的重载中删除一个元素(例如,一个迭代器对) )。

答案 1 :(得分:0)

如果在循环内增加迭代器(取决于是否擦除元素),则可以在迭代时进行擦除。如果删除它,则erase方法将返回向量中的下一个迭代器,如果没有,则自己增加它。此外,您需要将迭代器初始化为begin

vector<node>::iterator it;
for(it=vector_of_node.begin();it!=vector_of_node.end();){
    if(it->get_name()=="MARIA")
        it = vector_of_node.erase(it);
    else
        ++it;
}
相关问题