Подтвердить что ты не робот

С++ 11: Безопасно ли удалять отдельные элементы из std:: unordered_map во время итерации?

Рассмотрим канонический алгоритм удаления элемента из ассоциативного контейнера при итерации:

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 во время итерации?

4b9b3361

Ответ 1

Изменить: Опасности NoScript. У меня был запуск noscript, который отображал вкладки C11 и C14 в виде одного окна. Преторианский ответ правилен в том, что он гарантирован на практике и формализован в c14.

** Ниже неверно из-за noscript.

В нижней части cplusplus указано, что

Исключены только итераторы и ссылки на удаленные элементы.

Остальные не затронуты.

Относительный порядок итерации элементов, не удаленных операцией, сохраняется.

http://www.cplusplus.com/reference/unordered_map/unordered_map/erase/

В верхней части страницы он указывается для С++ 11... поэтому, если они не обновили его для С++ 14, я думаю, что это относится и к С++ 11. Преториан должен ответить, и вы должны проверить его за ответ, потому что даже если он не гарантирован в стандарте для С++ 11 (С++ 14 является патчем для такого рода вещей), он гарантирован на практике.

Я не мог найти стандарт STL, я, кажется, потерял его, или я посмотрю, есть ли текст, на который я мог бы указать.: -/