Есть несколько ответов на StackOverflow, которые предполагают, что следующий цикл - прекрасный способ стереть элементы из std::unordered_map
, которые удовлетворяют некоторому предикату pred
:
std::unordered_map<...> m;
auto it = m.begin();
while (it != m.end())
{
if (pred(*it))
it = m.erase(it);
else
++it;
}
Меня особенно интересует С++ 11 (в отличие от С++ 14) и следующая зловещая note на cppreference.com предполагает, что указанный выше цикл зависит от поведения undefined и может не работать в С++ 11:
Порядок элементов, которые не стираются, сохраняется (это позволяет стирать отдельные элементы во время итерации через контейнер) (поскольку С++ 14)
См. также Заголовок 2356. Стабильность стирания в неупорядоченных ассоциативных контейнерах, которая содержит запрошенную формулировку, измените на Рабочий проект N3797, пункт 14 на стр. 754 (добавление дополнительной фразы "и сохранение относительного порядка..." ).
Эта формулировка относится к N3797.
Измените [unord.req], p14, как указано:
-14- Элементы insert и emplace не влияют на действительность ссылок на элементы контейнера, но могут аннулировать все итераторы на контейнер. Члены стирания аннулируют только итераторы и ссылки на стертые элементы и сохранить относительный порядок элементы, которые не стираются.
Если моя интерпретация примечания cppreference.com верна, и указанный выше цикл зависит от поведения undefined в С++ 11, то какой наиболее эффективный способ решить эту проблему в С++ 11?