2015-10-30 2 views
3

Я хочу, чтобы контейнер хранил уникальные std :: weak_ptrs. std: set требует оператора <, предположительно потому, что он хранит элементы в дереве. Мое беспокойство заключается в том, что я реализую оператор < очевидным образом (уничтожен ptr = null ptr < действительный ptr), тогда этот результат может мутировать после добавления элементов в контейнер, что может сломать его.Можно ли хранить изменяющийся объект в наборе stl?

На самом деле это безопасно? Если нет, какие-либо предложения для контейнера?

С уважением

+2

Не похоже на стандартное значение std :: less на моем gcc для weak_ptrs – Sam

+0

'operator <' похоже, не определено для 'weak_ptr', поэтому' less' не будет работать. – skypjack

+0

Помогло ли это? http://en.cppreference.com/w/cpp/memory/owner_less – skypjack

ответ

0

Вы не можете использовать weak_ptr S в качестве ключей, если не используется сравнение владельца на основе (по сравнению со стоимостью на основе одного, что даже не определено для weak_ptr, для которых пытаются использовать оператора < приводит к ошибке) , Проблема в том, что срок их действия может истекать, и порядок ваших контейнеров (set, а также map) не будет более последовательным.

Как правильно указано Kerrek SB (простите меня, но мобильное приложение не позволяет мне правильно связывать пользователей), и, как вы можете прочитать из моей ссылки в комментариях, вы можете положиться на std::owner_less, начиная с C++ 11.

Действительный подход заключается в использовании set определяется как это следующим образом:

std::set<std::weak_ptr<C>, std::owner_less<std::weak_ptr<C>>> 

owner_less Обратите внимание, что может быть менее многословным, поскольку он автоматически выводит тип.

Имейте в виду, что этот подход не позволяет вам использовать метод expired во время посещения set, поскольку он все еще может содержать истекшие объекты, даже если они упорядочены.

Кроме того, обратите внимание, что существует большая разница между просроченным weak_ptr и пустым, поэтому сравнение с владельцем может быть не таким интуитивно, даже если истечение не должно повлиять на него, когда оно использовалось вышеприведенным подходом.

Heresomelinks.

1

user3159253 является правильным. Найден полный ответ здесь: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1590.html

 weak_ptr::operator< 

Поскольку weak_ptr может истечь в любое время, это не возможно заказать слабые указатели, основанные на их стоимости. Доступ к значению удаленного указателя вызывает неопределенное поведение, а трюки reinterpret_cast тоже не подходят, поскольку одно и то же значение указателя может быть повторно использовано следующим новым выражением. Использование p.lock(). Order() для упорядочения аналогично ошибочно, так как это означает, что значение p < q может измениться, когда p или q истекает. Если p и q являются членами std :: set, это нарушит его инвариант. Единственная практическая альтернатива заключается в том, чтобы заказывать слабые указатели по адресу своего блока управления, как это требует настоящая спецификация.

+0

Эта статья - хорошая находка. Во-первых, я ожидал, что порядок слабых указателей будет сохранен после истечения срока. TIL! – sehe

Смежные вопросы