C++ 从std::vector连续擦除的安全方法?

C++ 从std::vector连续擦除的安全方法?,c++,vector,iterator,C++,Vector,Iterator,我原以为下面的代码可以工作,但当目标小部件位于向量末尾时,它崩溃了 for(std::vector<AguiWidget*>::iterator it = children.begin(); it != children.end(); ++it) { if((*it) == widget) it = children.erase(it); } for(std::vector::iterator it=child

我原以为下面的代码可以工作,但当目标小部件位于向量末尾时,它崩溃了

for(std::vector<AguiWidget*>::iterator it = children.begin();
        it != children.end(); ++it)
    {
        if((*it) == widget)
            it = children.erase(it);
    }
for(std::vector::iterator it=children.begin();
it!=children.end();++it)
{
if((*it)=小部件)
它=儿童。擦除(它);
}
我希望它通过并删除它找到的任何小部件实例。我知道这个方法是N^2,但因为它是事件驱动的,所以它是好的。我只是不知道为什么会失败。当它这样做时,'it'==widget


谢谢

您可以使用“擦除-删除”习惯用法来擦除所有与
小部件
相等的元素

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

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

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

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

您知道您在比较指针,而不是解引用,对吗

你能告诉我们如果你使用“删除-擦除”习惯用法会发生什么吗?这将是快速(比您的代码更快)和正确的:

children.erase(std::remove_if(children.begin(), children.end(),
                              std::bind1st(std::equal_to<AguiWidget*>(),
                                           widget)));
children.erase(std::remove_if(children.begin(),children.end(),
std::bind1st(std::equal_to(),
),;
另外,不要忘记先删除指针

for_each_if(children.begin(), children.end(),
            std::bind1st(std::equal_to<AguiWidget*>(), widget),
            Delete());
对于每个如果(children.begin(),children.end(),
std::bind1st(std::equal_to(),小部件),
删除());

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

为了补充
高炉
的答案,您还可以使用一个简单的
for
循环来完成此操作,如果您反向操作的话

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

这是原始for()循环失败的关键原因。它总是在重新测试循环终止条件之前增加迭代器。将循环体中的迭代器更改为end(),然后尝试
++it
,会让你陷入愚蠢的境地。这里没有理由使用列表。@Matthieu:我之所以提到这一点,是因为对于涉及删除内部元素的任务,列表比向量更有效。虽然使用向量执行此任务完全是代码合法的,但每次删除都会受到很大的惩罚,因为以下所有项都需要在内存中移动,这可能涉及大量的复制和内存重新分配。列表不会遇到这个问题,因为它们可以重新排列几个指针来完成相同的任务。