Consider the following code:
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);
The goal is to remove inactive items from the list immediately after updating them, avoiding the need for a second pass. However, attempting to remove elements within the loop using the commented-out lines results in the error "List iterator not incrementable."
The key to safely removing elements during iteration is following the correct sequence of operations. Instead of the for loop approach shown above, the code should be modified to a while loop as demonstrated below:
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; } }
By first incrementing the iterator (i ), the iterator remains valid and can be used to remove the inactive element.
In the original for loop, attempting to remove an element using items.remove(*i) within the loop body invalidated the iterator (i), causing the subsequent iteration to fail. The while loop ensures that the iterator is updated before the element is removed, ensuring its validity for the following iteration. By using items.erase(i ) or i = items.erase(i), the appropriate element is removed from the list, and the iterator is automatically updated to point to the next valid element.
This approach allows for the efficient removal of inactive items during iteration without the need for a separate pass through the list.
The above is the detailed content of How to Safely Remove Elements from a std::list While Iterating?. For more information, please follow other related articles on the PHP Chinese website!