unordered_map указатель на значение элемента, действительное после изменения размера? - PullRequest
0 голосов
/ 05 ноября 2018

Если у меня есть unordered_map<key, someNiceObject>

(примечание someNiceObject не указатель)

У меня есть API, который вставляет новый элемент, а затем возвращает указатель на someNiceObject теперь на карте.

Если я выполню дальнейшие вставки в карту, возможно, произойдет изменение емкости. Если это произойдет, указатель остается в силе или нет?

Я пытался читать Основные вопросы: указатели на объекты в unordered_maps (C ++) , std :: unordered_map указатели / аннулирование ссылок и http://eel.is/c++draft/unord.req#9

и не удалось найти необходимую информацию

Спасибо всем

edit: кажется, что указатель будет действительным (https://www.thecodingforums.com/threads/do-insert-erase-invalidate-pointers-to-elements-values-of-std-unordered_map.961062/)

хотя был бы признателен за второе подтверждение от кого-то здесь на SO

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

std::unordered map необычно тем, что правила аннулирования итераторов НЕ применяются к ссылкам на элементы (исключая удаление, но что вы можете сделать, когда элемент пропал?). Изменение емкости не важно. Проблема в том, когда unordered map перезагружается. Перефразировка сделает недействительными все итераторы, но не сделает недействительными ссылки.

С пункта 9 [unord.req] в стандарте C ++ (со ссылкой на n4618, потому что это то, что у меня под рукой в ​​данный момент),

Элементы неупорядоченного ассоциативного контейнера организованы в ведра . Ключи с одинаковым хеш-кодом появляются в том же сегменте. Количество сегментов автоматически увеличивается при добавлении элементов в неупорядоченный ассоциативный контейнер, так что среднее количество элементов в сегменте остается ниже границы. Перефразировка делает недействительными итераторы, изменяет порядок элементов и изменения, в которых элементы сегментов появляются, , но не делает недействительными указатели или ссылки на элементы. Для unordered_multiset и unordered_multimap перефразировка сохраняет относительный порядок эквивалентных элементов. ,

Ударная мина

0 голосов
/ 05 ноября 2018

Согласно cppreference :

Если перефразирование происходит из-за вставки, все итераторы становятся недействительными. В противном случае итераторы не будут затронуты. Ссылки не являются недействительными.

Что означает, что указатели также не становятся недействительными. Это возможно потому, что концептуально std::unordered_map можно представить как std::vector<std::forward_list<std::pair<Key, Value>>>. А поскольку std::forward_list, как и любой другой связанный список, выделяет каждый элемент отдельно, изменения в списке не влияют на расположение его элементов в памяти.

...