When iterating through a set, it is necessary to remove certain elements based on specific criteria. While it might seem logical to assume that erasing an element would invalidate the iterator, this behavior is implementation-dependent.
Standard 23.1.2.8 states that "The insert members shall not affect the validity of iterators and references to the container, and the erase members shall invalidate only iterators and references to the erased elements." Based on this, it cannot be assumed that deleting an element while iterating would always invalidate the iterator.
One approach is to use a postfix increment operator it after deleting an element. This passes the old position to the erase function while simultaneously pointing the iterator to a newer position:
for (auto it = numbers.begin(); it != numbers.end(); ) { if (*it % 2 == 0) { numbers.erase(it++); } else { ++it; } }
Another method involves copying the current iterator and incrementing it later:
while (it != numbers.end()) { // Copy the current iterator and increment it std::set<int>::iterator current = it++; int n = *current; if (n % 2 == 0) { // Don't invalidate iterator it, as it points to the next element numbers.erase(current); } }
C 11 simplifies this process with the erase function returning an iterator to the element following the last removed element:
for (auto it = numbers.begin(); it != numbers.end(); ) { if (*it % 2 == 0) { it = numbers.erase(it); } else { ++it; } }
The above is the detailed content of How to Safely Delete Elements from a `std::set` While Iterating?. For more information, please follow other related articles on the PHP Chinese website!