Почему std::weak_ptr‹› не обеспечивает логическое преобразование?

std::shared_ptr‹> в C++11 предоставляет своего рода логический оператор.

operator unspecified-bool-type() const;

(Это не прямой operator bool() const из-за опасности от неявного приведения типа bool.)

Почему в std::weak_ptr‹> нет аналогичного оператора? ловлю себя на том, что постоянно печатаю

if( !wp.expired() )

когда я хочу напечатать

if( wp )

Почему нет логического преобразования для weak_ptr?


person OldPeculier    schedule 23.04.2012    source источник
comment
Потому что функции не реализованы по умолчанию?   -  person Lukasz Madon    schedule 23.04.2012
comment
operator bool теперь можно безопасно выполнять напрямую в C++11: stackoverflow.com/a/6242355/46642   -  person R. Martinho Fernandes    schedule 23.04.2012


Ответы (1)


if(!wp.expired()) почти всегда является неправильной проверкой в ​​многопоточном коде, потому что сразу после этого оператора if срок действия указателя может истечь. Таким образом, если бы weak_ptr имело именно такую ​​семантику для преобразования bool, оно все равно никогда не использовалось бы.

Если вы хотите проверить, жив ли указатель, используйте lock и проверьте полученный shared_ptr.

Если вы хотите знать, мертв ли ​​указатель, используйте expired.

Как видите, просто не имеет смысла обеспечивать логическое преобразование. Для shared_ptr вполне подходит. Кстати, оператор преобразования explicit operator bool() const noexcept; в C++11.

person Xeo    schedule 23.04.2012
comment
Если вы хотите проверить, жив ли указатель, используйте блокировку и проверьте полученный shared_ptr. Опасно, потому что вы можете отбросить последний сильный указатель на объект, поэтому вы можете сделать это только в контексте в котором было безопасно вызывать деструктор объекта. - person David Schwartz; 10.04.2016
comment
Я бы предположил, что любой контекст безопасен для вызова деструктора любого объекта, потому что деструкторы должны быть написаны таким образом, чтобы их можно было безопасно вызывать в любое время (AIUI, это должно быть так, чтобы обработка исключений работала в общем случае , так как раскручивание стека может уничтожить любой произвольный объект). Хотя мне был бы интересен контрпример. - person Keiji; 31.05.2016
comment
Ну, есть объекты, деструктор которых может выкинуть или вызвать нежелательные побочные эффекты. Но такие объекты никогда не должны быть заключены в shared_ptr в первую очередь. - person Kai Petzke; 25.06.2019
comment
просто не имеет смысла обеспечивать логическое преобразование: я не согласен. Если я хочу проверить, пусто ли weak_ptr, например. построено по умолчанию, правильная семантика - это operator bool. Использование expired семантически подразумевает, что когда-то оно было действительным. - person lornova; 06.09.2019