矢量擦除不会“擦除”第一个元素

时间:2015-09-16 12:59:48

标签: c++ vector erase

编辑器是一个vector :: iterator对象,列表显然是一个向量。

我想知道为什么它不会(vector).erase()列表的第一个元素,当我尝试只使用1个项目时,它会抛出异常。

for (editor = list.begin(); editor < list.end(); ++editor)
    if (*editor == title)           
        list.erase(editor);

4 个答案:

答案 0 :(得分:4)

优先于手写循环的算法。如果你只是这样做,你们中间没有人会担心:

list.erase(std::remove(list.begin(), list.end(), title), list.end());

P.S。在旁注中,我强烈反对将对象命名为STD类型(list是std :: type),甚至更多,命名它们以便它们匹配不同的容器类型。

答案 1 :(得分:1)

迭代向量时擦除并不像看起来那么简单,并且可能导致迭代器失效。

在不使迭代器失效的情况下执行此操作的正确方法是:

editor = list.begin();
while (editor < list.end()) {
    if (*editor == title)
        list.erase(editor++);
    else
        ++editor;
}

这可以确保在擦除元素时迭代器不会失效。

  

请注意operator++使迭代器前进,但返回前迭代器位置(要删除的位置)要擦除。

您也可以在某些星座中使用std::removestd::remove_if

有关详细信息,请参阅此问题: std::vector iterator invalidation

答案 2 :(得分:0)

问题不在于擦除;问题是你希望之后使用相同的迭代器(与end()进行比较)。如果您在删除元素后立即从break循环中for,它就会起作用。

答案 3 :(得分:0)

你确定它是第一个而不是后续的吗?

对向量进行擦除变异后,所有迭代器都会失效(包括end),因此您必须重新构建每个迭代器或中断并在擦除后立即退出循环。

for (editor = list.begin(); editor < list.end(); ++editor)
{
    if ( *editor == title )
    {
        size_t pos = editor - list.begin() ; // here's where we are now
        list.erase ( editor ) ;
        editor = list.begin() + pos ; // rebuild the iterator
    }
}

或者

for (editor = list.begin(); editor < list.end(); ++editor)
{
    if ( *editor == title )
    {
        list.erase ( editor ) ;
        break ; // stop iterating
    }
}