Solution: Add a new class std::nonowning_ptr<> representing a pointer that does not own a resource (it plays a similar role as weak_ptr<> to shared_ptr<>).
Problem: annoyingly, std::unique_ptr<> cannot be passed to a function by value.
Consider "old C++" code:void process(Widget* w){w->do_something();delete w; // nasty run-time error: w will be deleted again}void main(){Widget* w=new Widget();process(w);delete w;}Let's try to rewrite it with std::unique_ptr<>://void process(unique_ptr<Widget> w){ // problem - unique_ptr cannot be passed by value!
void process(unique_ptr<Widget>& w){ // extra level of indirection - potentially inefficientw->do_something();delete w; // syntax error now - good}void main(){auto w=make_unique<Widget>();process(w);// delete w; - no longer needed}
Solution: Add a new class std::nonowning_ptr<> representing a pointer that does not own a resource (it plays a similar role as weak_ptr<> to shared_ptr<>).
If you are already editing code to take advantage of this, just don't call delete. Heck, good code rarely calls delete *anywhere* except in the deleter of a smart pointer.
It seems like a lot of complexity (for users and not just the library) with very little benefit. Of course, if there are existing implementations with years of experience already, I'm willing to reconsider.
Functions that operate on a T but don't deal with ownership should
have the same signature as usual: f(T&) or f(T const&), or similar
with pointers. C++11 or unique_ptrs don't change that. Functions that
operate on a T but don't deal with ownership are just *normal*. You
pass them references to objects, not ownership handles.
See "A Proposal for the World's Dumbest Smart Pointer",
http://open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3514.pdf
We have handle that completely transfers/holds ownership (unique_ptr), we have a handle
that shares ownership (shared_ptr), but we have no handle that doesn't transfer/hold ownership
at all. T* does all of that and none of that depending on how people use it, and fails to convey
the semantics at a glance in a function signature.
That looks like a weak_ptr.
But would QPointer have use if it didn't have the ability to check
validity and was purely for semantic value? I see the validity check
Yes (imho), as would a non-owning "smart" pointer in general, because it tells
people at-a-glance what the ownership transfer (or more precisely, the lack of
it) is. T* doesn't do that. T& doesn't work for cases when the incoming valuemay be non-existent. optional<reference_wrapper<T>> comes close, if we
want to look for a decent alternative.
Um, I mean that T* means "non-owning pointer", except in places where
it means "owning pointer" because we haven't yet switched everything
over to scoped_ptr.
On 8 July 2013 22:04, Jeffrey Yasskin <jyas...@google.com> wrote:
Um, I mean that T* means "non-owning pointer", except in places where
it means "owning pointer" because we haven't yet switched everything
over to scoped_ptr.
Well, in each and every project I have worked on, whenever any ofT* f(U*);void f(T*);T* f();
T* member;appears, code reviewers start asking questions about ownership, without exception.It would actually save time and money to have a standardized vocabulary type that
says "ownership is not transferred". The existing practice for these is to consider whether
it's worth the trouble to add a custom non-transferring dumb pointer (which has to be
separately taught since people won't recognize it from other projects), or to just comment
the signatures and hope for the best, usually picking the latter, and then debugging
like mad.
--In my code bases, raw pointers are rare and usually used for calling C APIs, for which all this becomes is noise.
says "ownership is not transferred". The existing practice for these is to consider whetherit's worth the trouble to add a custom non-transferring dumb pointer (which has to be
separately taught since people won't recognize it from other projects), or to just comment
the signatures and hope for the best, usually picking the latter, and then debugging
like mad.
So, why haven't you introduced it to your code base? I don't mean that facetiously. I would not want to adopt something like this
> Well, in each and every project I have worked on, whenever any ofI'd like to double-check that these projects were started after C++11
> T* f(U*);
> void f(T*);
> T* f();
> T* member;
> appears, code reviewers start asking questions about ownership, without
> exception.
was released and that they use std::unique_ptr, std::shared_ptr, or
some other smart point to hold every owned pointer?
If your experience (like most of ours) is still mostly on transitional
projects, I do agree that the exempt_ptr would save some communication
time during the transition, but it won't speed up the transition to
unique_ptr, and I expect that once we're done with the transition,
exempt_ptr will just be a verbose wart.
By the way, what were the reactions on the official mailing list (which is not readable publicly) to N3514 and N3339?
I can't find any in-meeting discussions on either of them. Walter wasn't present in either Portland or Bristol.
These papers need a champion...
On 8 July 2013 16:33, Ville Voutilainen <ville.vo...@gmail.com> wrote:
I can't find any in-meeting discussions on either of them. Walter wasn't present in either Portland or Bristol.
I thought Walter was in Portland.
I know that dumb_ptr was briefly discussed in Bristol in LEWG (it was one of the very last things discussed). The sentiment in the room was that it should be investigated, along with other slightly different smart pointers (such as dumb but moveable).
I don't think clone_ptr has been discussed since Kona.
These papers need a champion...
I assume Walter will be at the Chicago meeting, given he is relatively local.
On 9 July 2013 00:43, Nevin Liber <ne...@eviloverlord.com> wrote:
On 8 July 2013 16:33, Ville Voutilainen <ville.vo...@gmail.com> wrote:
I can't find any in-meeting discussions on either of them. Walter wasn't present in either Portland or Bristol.
I thought Walter was in Portland.
Me too, first, but the minutes etc. show him absent.
I know that dumb_ptr was briefly discussed in Bristol in LEWG (it was one of the very last things discussed). The sentiment in the room was that it should be investigated, along with other slightly different smart pointers (such as dumb but moveable).
On 9 July 2013 05:14, Jonathan Wakely <c...@kayari.org> wrote:
On Monday, July 8, 2013 10:43:11 PM UTC+1, Nevin ":-)" Liber wrote:I know that dumb_ptr was briefly discussed in Bristol in LEWG (it was one of the very last things discussed). The sentiment in the room was that it should be investigated, along with other slightly different smart pointers (such as dumb but moveable).
More accurately (since dumb_ptr is also movable) the case I raised was a non-owning pointer that is dumb and **guaranteed to be null when moved-from**. That is useful as a data member (rather than in function signatures) because it makes it easier to follow the Rule of Zero and is a useful building block for smarter types.
Instead of that being a smart pointer, I'd rather have a more general template that can be applied to any scalar type, such as (warning: this is just proof of concept code):
More accurately (since dumb_ptr is also movable) the case I raised was a non-owning pointer that is dumb and **guaranteed to be null when moved-from**. That is useful as a data member (rather than in function signatures) because it makes it easier to follow the Rule of Zero and is a useful building block for smarter types.
Instead of that being a smart pointer, I'd rather have a more general template that can be applied to any scalar type,