简体   繁体   中英

How to erase element from vector and update iterator?

I am trying to delete a object from a vector at a specific index. The vector iterator keeps track of the index throughout the program. In the below code, the first IF statement works perfectly. But, if the iterator is pointing to anywhere OTHER than the last element, I erase the element from the vector and then increment the iterator. The program crashes and says "iterator not incrementable".

I ran the debugger several times and everything looks correct, so I cannot see what I am missing?

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 invalidates the iterator, so you can't use it afterwards. But it helpfully returns an iterator to the element after the removed one:

myVectorIterator = myVector.erase(myVectorIterator);

This is because the call to erase invalidates all iterators. Imagine you have something pointing to an element and that element disappears, what shall you point to?

Worse still, the behavior is highly implementation dependent. The correct approach is to store use the return value from erase which will be an iterator to the next element in the vector.

myVectorIterator = myVector.erase(myVectorIterator);

Note that you now have to remove the incrementation on the next line (or you will skip an item.)

In general, when manipulating different STL containers, you will see that in the documentation whether a given operation will have an effect on iterators. If you take a look at this link, you will see that for vector::erase this is the case:

"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."

Different containers may have different guarantees when it comes to iterator validity.

You have to do this

myVectorIterator = myVector.erase(myVectorIterator);

It will remove the current iterator then assign the next item into it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM