There are several answers on StackOverflow that suggest that the following loop is a fine way to erase elements from a std::unordered_map
that satisfy some predicate pred
:
std::unordered_map<...> m;
auto it = m.begin();
while (it != m.end())
{
if (pred(*it))
it = m.erase(it);
else
++it;
}
I'm specifically interested in C++11 (as opposed to C++14), and the following ominous note on cppreference.com suggests that the above loop depends on undefined behavior and may not work in C++11 after all:
The order of the elements that are not erased is preserved (this makes it possible to erase individual elements while iterating through the container) (since C++14)
See also Title 2356. Stability of erasure in unordered associative containers which contains a requested wording change to Working Draft N3797 item 14 on page 754 (the additional phrase beginning ", and preserve the relative order ...").
This wording is relative to N3797.
Modify [unord.req], p14 as indicated:
-14- The insert and emplace members shall not affect the validity of references to container elements, but may invalidate all iterators to the container. The erase members shall invalidate only iterators and references to the erased elements, and preserve the relative order of the elements that are not erased.
If my interpretation of the note from cppreference.com is correct, and the above loop depends on undefined behavior in C++11, what's the most efficient way to solve this problem in C++11?