
On Mon, Feb 11, 2013 at 1:47 PM, Peter Dimov <lists@pdimov.com> wrote:
read_ptr<T> pr;
if( write_ptr<T> pw = pr.write() ) { pw->mutate(); pr = std::move( pw ); }
I don't, however, particularly like the semantics of the case in which pr is already unique.
In fact, now that I think of it, .write should be a move, too.
In the case that pr has a use_count of 1, definitely. I thought that's what you had been proposing all along :) Deep copy the pointed-to object only if the use_count >= 2. Whatever you get back, do your mutations, then pass it back to the read_ptr. In this case, it's wouldn't be surprising to sometimes find pr holding a
NULL after the move.
write_ptr<T> pw = std::move( pr ); pw->mutate(); pr - std::move( pw );
The advantage here is that (1) in
read_ptr<T> get_value(); write_ptr<T> p = get_value();
you don't need a write() call,
I would expect most of the time you're not going to be immediately modifying a read_ptr rvalue like above. The typical use case I'd expect is you have existing read_ptr lvalue which points to an object you want to mutate. So whether you write .write() or move(pr) is not a huge syntactic difference. and (2) this avoids the mistake of doing
pr.write();
without storing the return value and as a result, losing *pr when it's unique. Just doing
std::move( pr );
would do nothing, so it's safer.
That's a fair point, but I think this is really an abuse of rvalue reference syntax :) I guess one concern I have is if you're moving a smart ptr, I'd expect it to be as fast as a couple pointer assignments, but here it could incur a deep copy, and that behavior is entirely runtime-dependent. - Jeff