On Thu, Jul 24, 2014 at 12:53 AM, Gavin Lambert
Hi all,
Firstly, any chance this could get some documentation? Is the author still around?
I'm still around, although not super-active. I'm personally neutral towards the code and whether its use should be encouraged. It has some pitfalls for the unwary, but there also seems to be recurring desire for the functionality. Also, it doesn't need CRTP they way enable_shared_from_this does.
I'm thinking about using this at the moment for two separate reasons (and ways in which enable_shared_from_this seems to fall short):
1. shared_from_this can't be used from the constructor (requiring factory-method-init shenanigans); reportedly (https://groups.google.com/forum/#!topic/boost-list/8JWFZ56ry6k) shared_from_raw can, although I can't find specific details on the caveats mentioned.
The two dangers that come to mind are: 1) you throw out of your constructor after handing out shared_ptrs/weak_ptrs, which reference an object which ultimately was never constructed. 2) you call shared_from_raw, but never actually give ownership of the object to an external shared_ptr. This results in the object holding a shared_ptr to itself, potentially indefinitely.
2. What I *really* want to be able to do is to create a child object (most commonly a callback functor) that contains a weak_ptr, and it seems silly (and badly performant) to use the usual factory-init pattern to call shared_from_this just to degrade it back to a weak_ptr.
And it should be possible to obtain that weak_ptr before any shared_ptr exists, and "fix" it later to point at the real shared_ptr, especially if it is known that the weak_ptr will never actually be used until that real shared_ptr exists.
enable_shared_from_raw almost seems to fit the bill (according to http://stackoverflow.com/questions/22184772/why-is-boostenable-shared-from-r...), but I encountered the same problem as in this post (http://lists.boost.org/boost-users/2013/05/78833.php); it works with shared_from_raw but not weak_from_raw.
However this change: https://github.com/boostorg/smart_ptr/pull/8 fixes that. It looks like the two calls went down different code paths for some reason I can't fathom.
I don't remember what the rationale was for the current behavior of weak_from_raw, or if I was the one who decided on that behavior. However, it seems like the current behavior could be useful in that it provides a way to query if an external shared_ptr ever actually took ownership of the object (or at least shared_from_raw has been used, which commits the coder to giving ownership to an external shared_ptr at some point).