Рассмотрим канонический алгоритм удаления элемента из ассоциативного контейнера при итерации:
for (auto iter = myMap.begin(); iter != myMap.end(); )
{
if (/* removal condition */)
{
iter = myMap.erase(iter);
}
else
{
++iter;
}
}
Я применяю этот алгоритм без второй мысли при использовании контейнера С++ 11 std::unordered_map
. Однако после просмотра документации для std::unordered_map::erase
на cppreference.com, я стал немного обеспокоен после прочтения следующего примечания:
Порядок элементов, которые не стираются, сохраняется (это позволяет стирать отдельные элементы во время итерации через контейнер) (поскольку С++ 14)
Основываясь на этом утверждении, я предполагаю, что язык был добавлен в стандарт С++ 14, чтобы гарантировать, что разработчики библиотеки гарантируют упорядочивание после вызова std::unordered_map::erase
. Например, может быть, такое требование ограничивает реализацию от не переименования всего контейнера после удаления элемента, а скорее только позволяет удалить элемент из его соответствующего ведра?
Без такой гарантии в С++ 11, и если я хочу, чтобы мой код был переносимым, мне нужно беспокоиться о том, что некоторые элементы будут посещаться несколько раз или вообще не будут удалены, если я удалю элемент из std::unordered_map
во время итерации?