c++liststdstdlist

Can you remove elements from a std::list while iterating through it?


I've got code that looks like this:

for (std::list<item*>::iterator i = items.begin(); i != items.end(); i++)
{
    bool isActive = (*i)->update();
    //if (!isActive) 
    //  items.remove(*i); 
    //else
       other_code_involving(*i);
}
items.remove_if(CheckItemNotActive);

I'd like remove inactive items immediately after update them, in order to avoid walking the list again. But if I add the commented-out lines, I get an error when I get to i++: "List iterator not incrementable". I tried some alternates which didn't increment in the for statement, but I couldn't get anything to work.

What's the best way to remove items as you are walking a std::list?


Solution

  • You have to:

    1. Increment the iterator (with i++).
    2. Remove the previous element (e.g., by using the returned value from i++).

    You can change the code to a while loop like so:

    std::list<item*>::iterator i = items.begin();
    while (i != items.end())
    {
        bool isActive = (*i)->update();
        if (!isActive)
        {
            items.erase(i++);  // alternatively, i = items.erase(i);
        }
        else
        {
            other_code_involving(*i);
            ++i;
        }
    }