【问题标题】:How to erase element from vector and update iterator?如何从向量中删除元素并更新迭代器?
【发布时间】:2014-09-04 13:12:43
【问题描述】:

我正在尝试从特定索引处的向量中删除一个对象。向量迭代器在整个程序中跟踪索引。在下面的代码中,第一个 IF 语句完美运行。但是,如果迭代器指向除最后一个元素之外的任何位置,我会从向量中删除该元素,然后递增迭代器。程序崩溃并显示“迭代器不可递增”。

我运行了几次调试器,一切看起来都正确,所以我看不到我缺少什么?

vector<Card> myVector; //container to hold collection of cards.
vector<Card>::iterator myVectorIterator; //points to each "card" in the collection.

Card Collection::remove() 
{
    if (myVectorIterator== myVector.end()-1) { //at the last card
        //erase the "current" card
        myVector.erase(myVectorIterator); 
        //update to the first card.
        myVectorIterator= myVector.begin();
       } 
    else
    {   

        myVector.erase(myVectorIterator); 

        //crashes here!
        myVectorIterator++;
    }

return *myVectorIterator;

}

【问题讨论】:

  • erase的返回值是一个迭代器,指向最后一个被擦除元素之后的元素的位置。

标签: c++ vector


【解决方案1】:

erase 使迭代器无效,因此以后不能使用它。但它有助于在删除的元素之后返回一个迭代器:

myVectorIterator = myVector.erase(myVectorIterator);

【讨论】:

  • 谢谢,这行得通。我查看了许多矢量文档,但找不到任何解释,叹息。
  • @astra:你试过this one吗?这通常是一个很好的参考。
【解决方案2】:

这是因为对擦除的调用使所有迭代器无效。想象一下,你有一个东西指向一个元素,而那个元素消失了,你应该指向什么?

更糟糕的是,该行为高度依赖于实现。正确的做法是使用erase的返回值来存储,该值将成为向量中下一个元素的迭代器。

myVectorIterator = myVector.erase(myVectorIterator);

请注意,您现在必须删除下一行的增量(否则您将跳过一个项目。)

一般来说,在操作不同的 STL 容器时,您会在文档中看到给定的操作是否会对迭代器产生影响。如果您查看此链接,您会看到对于 vector::erase 是这种情况:

"Iterators, pointers and references pointing to position (or first) and beyond are invalidated, with all iterators, pointers and references to elements before position (or first) are guaranteed to keep referring to the same elements they were referring to before the call."

在迭代器有效性方面,不同的容器可能有不同的保证。

【讨论】:

    【解决方案3】:

    你必须这样做

    myVectorIterator = myVector.erase(myVectorIterator);
    

    它将删除当前迭代器,然后将下一个项目分配给它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-02
      • 2015-04-21
      • 1970-01-01
      • 1970-01-01
      • 2017-10-24
      • 2016-04-15
      相关资源
      最近更新 更多