从std :: vector连续删除的安全方法?

时间:2010-11-14 02:31:03

标签: c++ vector iterator

我认为以下代码可以正常工作,但是当目标小部件位于向量的末尾时,它会崩溃。

for(std::vector<AguiWidget*>::iterator it = children.begin();
        it != children.end(); ++it)
    {
        if((*it) == widget)
            it = children.erase(it);
    }

我希望它能够通过并删除它找到的任何小部件实例。我知道这个方法是N ^ 2但是因为这是事件驱动的,所以很好。我只是不知道为什么会失败。当它发生时,'it'== widget。

由于

4 个答案:

答案 0 :(得分:7)

您可以使用擦除删除习惯用法删除等于widget所有元素。

children.erase(remove(children.begin(), children.end(), widget), children.end());

答案 1 :(得分:2)

如果你想像这样使用擦除,你应该坚持使用列表。但问题是你使迭代器失效,然后尝试增加它。试试这个。

for(std::vector<AguiWidget*>::iterator it = children.begin();
    it != children.end();)
{
    if(*it == widget)
        children.erase(it++);
    else
        ++it;
}

请注意,我没有在for-loop语句中增加迭代器。

答案 2 :(得分:0)

你确实意识到你正在比较指针,而不是解除引用,对吗?

你能告诉我们如果你使用删除 - 删除成语会发生什么?这将是快速的(比你的代码更快)并且正确:

children.erase(std::remove_if(children.begin(), children.end(),
                              std::bind1st(std::equal_to<AguiWidget*>(),
                                           widget)));

另外,不要忘记先删除指针。

for_each_if(children.begin(), children.end(),
            std::bind1st(std::equal_to<AguiWidget*>(), widget),
            Delete());

当然,你必须确保没有两个指针指向同一个对象。

答案 3 :(得分:0)

要补充Blastfurnace的答案,如果您向后执行此操作,也可以使用简单的for循环。

for (widgets::reverse_iterator it = children.rbegin(), end = children.rend();
     it != end; ++it)
{
  if (*it == widget) { children.erase(it.base()); }
}