std :: unordered_map :: извлечение ссылок / указателей, аннулирование - PullRequest
0 голосов
/ 10 октября 2018

Для новой функции C ++ 17 std::unordered_map::extract документация гласит:

Извлечение узла делает недействительными только итераторы для извлеченного элемента и сохраняет относительный порядок элементов, которые не являютсястерта.Указатели и ссылки на извлеченный элемент остаются действительными, но не могут использоваться, пока элемент принадлежит дескриптору узла: они становятся пригодными для использования, если элемент вставлен в контейнер.

Естественно, extract делает недействительнымитератор извлеченного (который является частью контейнера, из которого был удален элемент).Но в документации есть шутки о ссылках и указателях - там говорится, что они остаются действительными, но нельзя использовать до тех пор, пока они не будут вставлены в (возможно, в другой) контейнер - случай, в котором они сохранят свои значения (?).

Вопрос: Мой вариант использования состоит в том, чтобы исследовать элемент после извлечения, т.е. выполнить операцию erase-exam-discardForGood только с одним поиском хеша.Функция extract казалась идеально подходящей для этого, однако документация предполагает, что я не могу использовать node_type для проверки элемента.Правильно ли мое понимание?

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

Можно подумать, что extract (и соответствующий insert) «магическим образом» изменяет тип элемента карты, на который влияют: когда элемент принадлежит карте, он имеет тип std::pair<const key_type, mapped_type>, но когда элементпринадлежащий дескриптору узла, он имеет тип std::pair<key_type, mapped_type> (так что вы можете изменить значение ключа).

Таким образом, если вы получаете ссылку / указатель на элемент, когда элемент принадлежит карте, тогда вы не сможете использовать эту ссылку / указатель после извлечения элемента и до его повторной вставки, иначе вы нарушите строгое правило псевдонимов.

Однако использование ссылки / вполне допустимоуказатель, полученный после извлечения.

0 голосов
/ 10 октября 2018

Да, именно об этом говорится в тексте.

На первый взгляд это кажется довольно произвольным ограничением, хотя я уверен, что есть какая-то хорошая, хотя и загадочная, причина для этого.

При этом сам дескриптор имеет функции-члены value() / key() / mapped(), которые могут иметь для вас значение (!).

Дескриптор узла является типом только для перемещенияон владеет и предоставляет доступ к элементу (value_type), хранящемуся в узле, и обеспечивает неконстантный доступ к ключевой части элемента (key_type) и отображенной части элемента (mapped_type). ( ref )

...