Jeremy Maitin-Shepard wrote:
From reading the documentation, it seems that owner_ptr/data_ptr are basically equivalent in functionality to std::unique_ptr, and weak_ptr is basically equivalent to a raw pointer/raw reference. (Referring to std::shared_ptr seems a bit misleading given that you don't address the problem of multiple ownership.)
Well I think there are two ways to see it. I was motivated by both of them: std::unique_ptr + added safety + non-owning companion smart pointer type (as you suggested) or std::shared_ptr + std::weak_ptr - accidental cyclic ownership - runtime overhead I believe multiple ownership in std::shared_ptr is not a goal in itself, but just a way to ensure that objects stay live as long as they're needed. In my opinion I do actually address the problem of multiple ownership by taking it away. :-) As for the rich-typed weak_ptr, I think you should really think of it as a smart pointer, if only because it doesn't allow the user to deallocate the referenced object.
As I understand it, the goal of your library is not to add any functionality over std::unique_ptr, but to provide a little bit more compile-time safety at the cost of some additional typing (pun intended).
Well, yes. I do consider that additional functionality.
It does seem that wrappers around unique_ptr and shared_ptr that disable default construction and discourage storing a null pointer would be useful for many people. It would be much more useful if they explicitly interoperated with those types, though.
Fortunately it is trivial to add some interoperability with the std:: pointers. I'll add that to the roadmap.
I think the primary use case for your proposed weak_ptr (possibly renamed param_ptr or arg_ptr) would be as the declared type for function parameters.
That, and as a way to create arbitrarily complex linked data structures without introducing ownership problems. Note how this makes it more similar to std::weak_ptr than you may have thought initially. I do like your suggestion for the name param_ptr or arg_ptr, though. I've been considering whether I should split weak_ptr in two types, one for function arguments and one for linked data structures. In that case your name suggestions would be excellent for the former while I could keep using the name weak_ptr for the latter. This would allow me to enforce that the proposed param_ptr is always non-null so that functions can rely on that.
When used only in that context, the implicit conversion from an owning pointer to a raw pointer is safe, because any values used as function arguments are guaranteed to live for the duration of the function.
For any other use, though, the implicit conversion is actually dangerous,
Could you elaborate on why implicit conversion to my weak_ptr would be dangerous?
and I would say that the warning signal that syntax like:
T *x = foo.get();
or
T &x = *foo;
provides is helpful.
Since type deduction is only rudimental in C++11, there actually is such a warning signal: auto x = weak(foo); Hope this helps. Thanks for your feedback! -Julian