When is a `std::weak_ptr` empty?

Viewed 92

According to [util.smartptr.weak.obs]/4, the weak_ptr::owner_before strict weak ordering is such that "two shared_­ptr or weak_­ptr instances are equivalent if and only if they share ownership or are both empty."

However, I see nothing in the standard that defines what it means for a weak_ptr to be empty. Obviously a default-constructed weak_ptr is empty, and a weak_ptr constructed from an empty shared_ptr is empty, but it doesn't seem to be explicitly stated whether an expired weak_ptr is empty.

1 Answers

While I don't see it guaranteed by the Standard, usability1 of the owner_before ordering requires that:

  • A weak_ptr which has become expired2 is NOT EMPTY.

This is because only mutation of an object should change its placement in an ordering, and a weak_ptr may expire without ever being mutated.


1 For example, here someone has used weak_ptr as a key in std::set: How to compute hash of std::weak_ptr?. Doing that, and std::map likewise, requires the ordering to survive expiration. Were there to be an owner_hash to allow use with std::unordered_set and std::unordered_map, that hash would also have to survive expiration.


2 Note the subtle difference between "has become expired" and "is expired" -- a weak_ptr constructed empty, or assigned with an empty pointer value, has expired() == true. But it didn't expire (action verb), it was created in an expired state. My answer only applies to weak_ptr values which are at some point not expired, then (passively) become expired due to detachment of shared_ptr values from the target.

Related