On 25/07/2014 10:50, Frank Mori Hess wrote:
Also, it doesn't need CRTP they way enable_shared_from_this does.
I was wondering about that. Does it handle the case where a base class calls shared_from_raw with its own "this" pointer but the derived pointer is the one that ends up actually being externally owned? I think that (or something multi-inheritance-related) was the reason ESFT required CRTP? On a basic read-through of the code I *think* it's fine, but it never hurts to get confirmation. :)
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).
I don't think there's any difference in that commitment with shared_from_raw vs. weak_from_raw. Both of them are insufficient to give a "real" owning pointer by themselves -- according to the stackoverflow answer, any pointer obtained from either of these methods cannot "actually" own the pointer, and instead the real raw pointer has to be externally passed to a separate shared_ptr instance. So calling shared_from_raw from within the constructor gives you no additional guarantees (except that it actually works, at the moment, while weak_from_raw does not until this patch is applied). Neither provide a way to tell from the outside whether that second "real" shared_ptr was ever constructed -- to do that, you'd have to check that weak_this_ was *not* expired and shared_this_ *was* empty, if I'm following the code correctly. (Or conversely, you're in the danger state whenever shared_this_ is non-empty.) Maybe it would be useful to explicitly expose a way to query for that? Though to be honest other than unit tests and debugging I doubt anything would actually use it (but the same could be said of shared_ptr's use_count). If you think it will help, I could post a separate PR with the other style that I mentioned, which would make it more obvious that there's little difference between shared_from_raw and weak_from_raw, and then you (or whoever is in charge of SharedPtr at the moment) can choose which you prefer. I just initially went with the one-liner in the hopes that it'd be easier to get that into 1.56.