1
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)中消除多个对象(在称为节点的类中描述)。当我运行我的代码时,我没有从编译器得到任何错误,但是在它运行时我失败了。我确定错误出在我共享的这部分代码上。你能帮帮我吗?

4

3 回答 3

1

使用您当前的方法,即一个一个地擦除向量中的元素,擦除后的所有元素都必须移动到向量的前面。每次擦除元素的迭代都会执行此操作(仅当您擦除向量的背面时,元素才不会移动)。

作为替代方案,您可能需要考虑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()采用范围的相应重载(即迭代器对)的一次调用从向量中删除。

于 2019-12-03T19:19:31.147 回答
1

通过一次擦除一个来消除向量中的多个对象是非常低效的。每次erase调用都会将右侧的所有元素随机移动一个位置。已经有一个标准库模式可以更好地做到这一点,使用std::remove

std::erase(std::remove_if(vector_of_node.begin(),
                          vector_of_node.end(),
                          [](const node& n) { return n->get_name() == "MARIA"; }),
           vector_of_node.end());

的结果std::remove_if是重新排列的向量,所有匹配都移到了末尾,它返回一个迭代器到第一个匹配。然后你打电话std::erase把它们全部删除。

于 2019-12-03T19:23:46.357 回答
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;
}
于 2019-12-03T19:05:16.933 回答