我有代码看起来像这样:
for (std::list<item*>::iterator i=items.begin();i!=items.end();i++)
{
bool isActive = (*i)->update();
//if (!isActive)
// items.remove(*i);
//else
other_code_involving(*i);
}
items.remove_if(CheckItemNotActive);
我想在更新后立即删除非活动项目,以避免再次走过列表 . 但是如果我添加注释掉的行,当我到达 i++
时会出错:"List iterator not incrementable" . 我尝试了一些没有任何工作的替代品 .
当你走std :: list时,删除项目的最佳方法是什么?
11 回答
您必须首先递增迭代器(使用i),然后删除前一个元素(例如,使用i中返回的值) . 您可以将代码更改为while循环,如下所示:
你想做:
这将正确地更新迭代器以指向您删除的迭代器后的位置 .
您需要结合Kristo的答案和MSN:
当然,效率最高的SuperCool®STLsavy就是这样的:
使用std :: remove_if算法 .
Edit: 与馆藏合作应如下:1 . 准备馆藏 . 2.流程收集 .
如果你不混合这些步骤,生活会更容易 .
std :: remove_if . 或list :: remove_if(如果你知道你使用list而不是TCollection)
std :: for_each
Kristo答案的循环版本的替代方案 .
你会失去一些效率,你会向后退,然后在删除时再转发,但为了换取额外的迭代器增量,你可以在循环范围内声明迭代器,代码看起来更清晰一些 . 选择什么取决于当下的优先事项 .
答案完全没有时间,我知道......
下面是一个使用
for
循环的示例,该循环遍历列表并在遍历列表期间删除项目时递增或重新验证迭代器 .删除仅使指向已删除元素的迭代器无效 .
因此,在这种情况下,删除* i后,i无效,您无法对其进行增量 .
你可以做的是首先保存要删除的元素的迭代器,然后递增迭代器,然后删除保存的迭代器 .
你可以写
您可以使用
std::list::remove_if
编写等效代码,该代码更简洁,更明确当items是向量而不是列表时,应该使用
std::vector::erase
std::remove_if
成语以保持O(n)处的复杂性 - 或者如果您编写通用代码并且项目可能是一个没有有效方法来擦除单个项目的容器(如向量) )如果您将
std::list
视为一个队列,那么您可以将所有要保留的项目出列并排队,但只能将要删除的项目出列(而不是入队) . 这是一个例子,我想从包含数字1-10的列表中删除5 ...myList
现在只有1-4和6-10的数字 .我总结了一下,这里有三个方法,例如:
1.使用while循环
2.在列表中使用remove_if成员功能:
3.使用std :: remove_if功能结合擦除成员函数:
4.使用for循环,应注意更新迭代器:
我觉得你有一个bug,我这样编码: