
On 8 September 2011 08:10, Mostafa <mostafa_working_away@yahoo.com> 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@eviloverlord.com> (847) 691-1404