YES
Ссылка , которую вы уже цитировали в своих постах, ясно говорит о том, что элементы не копируются или перемещаются . (Это предполагает, что node
в вашем фрагменте кода не ссылается на map::node_type
).
То же самое относится к операции insert
узла карты (после изменения его ключа):
Если вставка прошла успешно, указатели и ссылки на элемент, полученные при его удержании в дескрипторе узла, становятся недействительными, а указатели и ссылки, полученные на этот элемент до его извлечения, становятся действительными. (начиная с C ++ 17)
Однако доступ к объекту между extract()
ion и re * insert()
имеет неопределенное поведение, и его адрес, полученный в извлеченном состоянии, имеет ограниченное использование. Цитирование из стандарта:
Члены извлечения делают недействительными только итераторы для удаленного элемента;
указатели и ссылки на удаленный элемент остаются действительными. Тем не мение,
доступ к элементу с помощью таких указателей и ссылок, в то время как
Элемент принадлежит node_type с неопределенным поведением. Ссылки и
указатели на элемент, полученный в то время как он принадлежит типу узла
становится недействительным, если элемент успешно вставлен.
Объяснение
По сути, map<>
реализован в виде дерева узлов, каждый из которых содержит key
и T
(которые отображаются как pair<const Key, T>
для пользователя). Узлы распределяются (обычно) в куче, а адрес вашего объекта связан с адресом узла. map::extract()
отсоединяет узел от его дерева и возвращает дескриптор узла (объект, содержащий указатель на узел карты), но AFAIK сам узел не перераспределяется, перемещается или копируется. После map::insert(handle)
узел повторно связывается с деревом в соответствии с его (новым) ключом. Опять же, это не требует перераспределения, перемещения или копирования узла.
Примечание
Выше приведен примерный набросок. То, как на самом деле все делается, вероятно, более сложное и также определяется реализацией Как объяснено здесь a node_handle
позволяет изменять клавишу с помощью функции-члена
Key &node_handle::key() const;
Как это делается под капотом, не указано, и я предполагаю, что реализация использует объединение или некоторую приведение для этого. Конечно, карта должна представлять пользователям pair<const Key,T>
, чтобы не дать им сменить ключ и, следовательно, сломать карту, но это не имеет значения для элемента, извлеченного из карты.