From: Peter Dimov (pdimov_at_[hidden])
Date: 2008-05-03 08:38:29
> On Friday 02 May 2008 08:18, Peter Dimov wrote:
> > What I had in mind is illustrated with the following:
> > X * px = new X;
> > // px->shared_from_this(); // throws bad_weak_ptr
> > weak_ptr<X> wx = px->weak_from_this(); // OK
> > assert( wx.use_count() == 0 ); // expired
> > shared_ptr<X> sx( px );
> > assert( wx.use_count() == 1 ); // shares ownership with sx
> It's not clear to me that this kind of behavior could be implemented for
> weak_ptr without changing its specification.
It's compatible with the specification of weak_ptr. use_count() returns the
number of shared_ptr instances in the ownership group. Before the shared_ptr
line, this number is zero, after it, it's one, exactly what is reported.
> Also, it doesn't allow for distinguishing between "object alive but no
> shared_ptr owner yet" and "shared_ptr expired or object destructed" cases.
Yes, it doesn't.
> For the use case of tracking signal/slot connections, the signal would
> want to be able to distinguish between the two cases, temporarily blocking
> the connection in the first, and disconnecting it permanently in the
In the first case, the signal should proceed to invoke the slots without the
one that is in process of being constructed. I agree that it makes it hard
to automatically disconnect the connection when its weak_ptr expires. In
theory, you can avoid this by simply not disconnecting automatically.
> What does seem to have the right semantics is for weak_from_this() to
> return something like a shared_ptr<weak_ptr<T> >. Every call would return
> a shared_ptr that points at the unique weak_ptr which will be assigned the
> object's owning shared_ptr.
It seems to me that now you have a data race on the weak_ptr target, which
would require synchronization.
There's a similar data race hidden in the above case as well, but it's not
visible to the user (and seems less fequent, although I could be wrong).