Boost logo

Boost :

Subject: Re: [boost] [optional] Thoughts on disallowing assignment for wrapped references.
From: Nevin Liber (nevin_at_[hidden])
Date: 2011-09-08 16:01:46


On 8 September 2011 08:10, Mostafa <mostafa_working_away_at_[hidden]> wrote:

> In what respects haven't I covered it?

Variables that are returned from functions are neither locals nor
class members; you don't know what the caller wants to do with it.

>> which again, is problematic for two reasons:
>>
>> (1)  Types that are Copyable but not Assignable are surprising
>
> Not necessarily, think of Pimpl.  If I have a Pimpl class heirarchy, then
> operator= becomes problematic for the base class, therefore I disallow it in
> all cases.

If you have an Impl class hierarchy, presumably you have to allocate
it on the heap, so why isn't the Pimpl just storing it in a
shared_ptr? That way, the compiler generated copy/move constructors
and assignment operators just work.

> What about using such a Pimpl in stl-like containers?  Answer, use the
> opaque handle of the Pimpl, and reconstruct the Pimpl from the opaque handle
> where necessary.

A Pimpl with a shared_ptr works perfectly well in STL-like containers.

You seem to revel in adding lots of complexity into what should be simple cases.

The few cases I've seen of Copyable but not Assignable classes
(including Pimpl) are those where the object cannot participate in the
ownership of some resource (usually for performance reasons). In my
world, a raw pointer/reference means the underlying object does not
participate in lifetime/ownership, so it captures that idea perfectly.
 If I want to disable assignment, all I have to do is make it a const
pointer. I just don't see what optional2 buys me. For a Pimpl, I
don't even see what having an optional Impl buys me if I can't ever
set it.

>> (2)  It is rare to return a reference anyway, as something outside of
>> the callee has to manage the lifetime of the underlying object
>
> Not that rare.  Let's say I'm using raw-pointer/reference idiom to convey
> the semantics of optionalness, then returning a reference is certainly an
> option.  I believe it's the callee that has to manage the said lifetime.

How? The callee *can't* manage the lifetime of the underlying object,
as all the local callee state is gone once the callee returns.
Something else has to manage the underlying object so that it lasts as
long as the caller needs it to exist (which may be longer than the
caller itself exists).

For instance, when vector::operator[] returns a reference, it assumes
something else is keeping the vector around and not invalidating that
reference for as long as that reference is needed. vector itself
cannot manage that.

Instead of making all these theoretical arguments, could you post some
code where this would actually be useful?

-- 
 Nevin ":-)" Liber  <mailto:nevin_at_[hidden]>  (847) 691-1404

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk