Deleting Elements from std::set During Iteration: Implementation Implications
Iterating through a set while removing elements can present challenges, as the operation could potentially invalidate the iterator. In this context, the question arises: is this behavior defined by the C standard or is it implementation-specific?
Implementation Dependency
According to the C standard (23.1.2.8), the insertion of elements into a set should not affect iterators or references to the container, while erasing elements should only invalidate iterators and references to the deleted elements. However, the behavior of iterators during erasing operations is not explicitly specified, leaving it open to implementation-specific decisions.
GCC Implementation
In the example code provided, using GCC 4.3.3 on Ubuntu 10.04, erasing elements from a set during iteration did not invalidate the iterator. This suggests that GCC's implementation follows a more relaxed approach, allowing for the continued use of the iterator after erasing.
Conforming Solution
To ensure standard conformance, a different approach is required. One common solution is to create a copy of the iterator before erasing the element:
for (auto it = numbers.begin(); it != numbers.end(); ) { if (*it % 2 == 0) { numbers.erase(it++); } else { ++it; } }
In this case, the postfix increment (it ) passes the old position to the erase() function while simultaneously jumping to the next element. Postfix increment is preferred here as it avoids the potential double-increment issue that can occur with prefix increment (when the condition is false).
C 11 Update
With the advent of C 11, a more elegant solution is available. The erase() function now returns an iterator to the element that follows the last element removed (or set::end if the last element was deleted). This allows for a more concise implementation:
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 Is Deleting Elements from a `std::set` During Iteration Defined Behavior in C or Implementation-Specific?. For more information, please follow other related articles on the PHP Chinese website!