Перемещение объекта из набора
Вы можете использовать extract
, чтобы удалить соответствующий узел из набора. Это дает вам ссылку на узел. Если у вас есть ручка, вы можете переместить предмет из ручки.
template<class T>
T find_and_remove(std::set<T>& s, T const& elem) {
auto iterator = s.find(elem);
if(iterator == s.end() {
throw std::invalid_argument("elem not in set");
}
// Remove element, return node handle
auto node_handle = s.extract(iterator);
return std::move(node_handle.value());
}
В качестве альтернативы, если у вас уже есть итератор для узла, вы можете написать его так:
template<class T>
T remove_from_set(std::set<T>& s, std::set<T>::iterator it) {
return std::move(s.extract(it).value());
}
Перемещение стоимости передает право собственности на любые ресурсы, которыми владеет стоимость. Например, если набор содержит строку, содержимое строки не будет удалено, и любые итераторы строки не будут признаны недействительными.
Предостережение заключается в том, что если у вас были указатели или ссылки на объект с того времени, когда он еще находился в наборе, они будут недействительными.
Извлечение самого объекта без движения и аннулирования любых указателей или ссылок на объект
Это менее распространенный случай, но если у вас есть ссылка или указатель на объект в наборе, вы можете сделать это.
Опять же, мы можем использовать функцию extract
:
auto node_handle = s.extract(my_object);
Или:
auto node_handle = s.extract(my_iterator);
Вы можете получить доступ к хранимому объекту с помощью node_handle.value()
, который возвращает ссылку на объект. Объект не будет удален до тех пор, пока не будет удален node_handle
, и если вам нужно продлить срок его службы, вы можете вернуть node_handle
из функции без удаления объекта.