unordered_map указатель на значение элемента, действительное после изменения размера?
Если у меня есть unordered_map<key, someNiceObject>
(нота someNiceObject
не указатель)
У меня есть API, который вставляет новый элемент, а затем возвращает указатель на someNiceObject
сейчас на карте.
Если я выполню дальнейшие вставки в карту, может произойти изменение емкости. Если это произойдет, указатель остается в силе или нет?
Я попытался прочитать Основные вопросы: указатели на объекты в unordered_maps (C++), std:: unordered_map указатели / аннулирование ссылок и http://eel.is/c++draft/unord.req#9
и не смог найти необходимую информацию
Спасибо всем
изменить: кажется, что указатель будет действительным ( https://www.thecodingforums.com/threads/do-insert-erase-invalidate-pointers-to-elements-values-of-std-unordered_map.961062/)
хотя был бы признателен за второе подтверждение от кого-то здесь на SO.
2 ответа
Согласно cppreference:
Если перефразирование происходит из-за вставки, все итераторы становятся недействительными. В противном случае итераторы не будут затронуты. Ссылки не являются недействительными.
Это означает, что указатели также не становятся недействительными. Это возможно, потому что std::unordered_map
концептуально можно думать как std::vector<std::forward_list<std::pair<Key, Value>>>
, И с тех пор std::forward_list
Как и любой другой связанный список, выделяет каждый элемент отдельно, изменения в списке не влияют на расположение его элементов в памяти.
std::unordered map
необычно тем, что правила аннулирования итераторов НЕ применяются к ссылкам на элементы (исключая удаление, но что вы можете сделать, когда элемент исчезнет)? Изменение емкости не важно. Проблема в том, когда unordered map
перефразирует. Перефразировка сделает недействительными все итераторы, но не сделает недействительными ссылки.
С пункта 9 [unord.req] в Стандарте C++ (со ссылкой на n4618, потому что это то, что у меня есть на данный момент),
Элементы неупорядоченного ассоциативного контейнера организованы в сегменты. Ключи с одинаковым хеш-кодом появляются в том же сегменте. Количество сегментов автоматически увеличивается при добавлении элементов в неупорядоченный ассоциативный контейнер, так что среднее количество элементов в сегменте остается ниже границы. Перефразирование делает недействительными итераторы, изменяет порядок между элементами и изменения, в которых появляются элементы сегментов, но не делает недействительными указатели или ссылки на элементы. За
unordered_multiset
а такжеunordered_multimap
Перефразировка сохраняет относительный порядок эквивалентных элементов.
акцент мой