For example:
std::weak_ptr<int> wp1(std::make_shared<int>());
std::weak_ptr<int> wp2;
assert(PointsToValidOrExpiredObject(wp1));
assert(!PointsToValidOrExpiredObject(wp2));
Is such a function possible?
Use case: A class's constructor takes std::weak_ptr<Foo>
as a dependency. Passing an expired object is ok (might happen in certain workflows), but passing null means the programmer forget something. I'd like to test for this as part of the constructor's parameter validation.
std::weak_ptr::owner_before
can distinguish between weak pointers that are empty and expired. You can therefore implement PointsToValidOrExpiredObject
as:
template <typename T>
bool PointsToValidOrExpiredObject(const std::weak_ptr<T>& w) {
return w.owner_before(std::weak_ptr<T>{}) ||
std::weak_ptr<T>{}.owner_before(w);
}
Demo.
Regarding the original uncertainty I had about an expired weak_ptr
still maintaining ownership: I'm now certain that the general library-wide thread-safety requirements mandate that an expired weak_ptr
continues to have the same ownership. Otherwise, destroying the last remaining shared_ptr
in thread A would have to observably modify the state of one/some/all weak_ptr
s that share ownership with the shared_ptr
in question. If thread B was simultaneously examining the state of such a weak_ptr
then you would have a data race introduced by the library implementation which is forbidden in general.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With