Boost logo

Boost :

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


On 31 August 2011 16:13, Mostafa <mostafa_working_away_at_[hidden]> wrote:
> I agree with you, and that's why, IMHO, implementations should follow
> existing conventions as much as possible.  And that's why I was exploring
> the disallowing of the assignment operator for optional<T&>, because in some
> use cases the behaviour of the assignment operation for optional<T&> is
> inconsistent with an existing convention, namely that of bare C++
> references.

I still contend that your mental model is wrong with respect to C++
references (but understandably so, as I'll get to).

Let's start with local objects. Take:

{
   Foo f;
   // f exists
   //...
} // f will shortly get destroyed

The lifetime of f is from when it is done being constructed until a
little after its enclosing scope is destroyed (at which time objects
are destroyed in reverse order of creation). Within that stack frame,
f exists exactly 1 time; no more, no less.

Now look at member variables:

struct Bar
{
    Foo f;
};

The lifetime of Bar::f is from when it Bar::f is constructed until
shortly after the Bar object is destroyed. Within any instance of
Bar, f exists exactly 1 time; no more, no less.

I'll call the above two examples the normal lifetime window. If you
pair up new/delete, I can define a similar window for heap based
objects as well, but by now you get the idea.

Moving on to boost::optional for objects:

{
    boost::optional<Foo> maybef;
    // ...
}

Within the normal lifetime window, the object maybef holds can exist 0
or more times. Those are the semantics boost::optional gives us.

Moving on to C++ references:

{
    Foo& reff /* what goes here depends on if it is a local or class
member... */;
    // ...
}

Within the normal lifetime window, the reff is bound to an object
exactly 1 time; no more, no less.

Given that, within the normal lifetime window, what would you expect
to happen for an optional reference:

{
    boost::optional<Foo&> maybereff;
    // ...
}

I see the same thing as all of the other cases, the "exactly 1 time"
is relaxed into "0 or more times".

So why do people get this wrong? We don't tend to be very precise
when we describe what happens in English.

We say "one cannot rebind a reference", which brings to mind "at most
1 time" semantics, and *we mentally separate that* from "bound at
construction time" ("at least 1 time" semantics), even though the two
are inextricably linked ("exactly 1 time" semantics).

-- 
 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