Boost logo

Boost :

From: Brian McNamara (lorgon_at_[hidden])
Date: 2003-10-30 15:51:24


Similar to recent variant discussions, (like Dave just did) I want to
offer the (same) advice that, without actual use cases from practical
experience, we should not be too confident/final with respect to results
from this discussion.

That said...

On Thu, Oct 30, 2003 at 04:41:54PM -0300, Fernando Cacciola wrote:
> int a = 1 ;
> optional<int&> opt(a) ;
>
> Ideally, initialized optional references should behave just like true
> references, thus, assignment should not rebind the reference to a different
> object but assign right into the referenced object:
>
> int b = 2 ;
> opt = b ;
> assert( a == b) ;

I don't agree that this is "ideal"; I'll argue why shorty.

> Currently, optional support for references _does not_ work like this:
> assignment rebinds the reference:
>
> opt = b ;
> b = 3 ;
> assert( *opt == 3 );

This seems right to me.

> Consider,
>
> optional<int&> def ;
> int a =1 ;
> def = a ;
>
> what should the last assignment do?
> It cannot do as described above (as true references) since there is no
> referenced object to assign to.

Exactly. I think this suggests the only reasonable ways to go, one of
which is to keep the current behavior. (The other is to leave the
behavior of assignments like these undefined (though with BOOST_ASSERT
help), just like if you assign to a dangling reference in C++.)

So here's my take. Given

   optional<T> o;

it should always be that

   o = x;

means the same thing as

   o = optional<T>(x);

As far as I can tell (based on your message above), this is how
optional currently behaves. IMO this is how it should be: to assign to
an optional, the new RHS must be another optional.

Now, if you want code like this:

> int a = 1 ;
> optional<int&> opt(a) ;
> int b = 2 ;
> opt = b ;
> assert( a == b) ;

to work, you should be writing

> int a = 1 ;
> optional<int&> opt(a) ;
> int b = 2 ;
> *opt = b ; // Note '*'
> assert( a == b) ;

instead. That is, if you want to change the value that is referenced
(rather than rebind the reference), you should say so explicitly.

Put another way: If you assign to an optional<T>, the value of the T
will change. In the case above, T is a reference, and thus assigning
to an optional<T> means that the "value of the reference" (that is, the
memory location it addresses) will change.

This jives with the view of "optional as a container" or "optional as a
pointer", which is the view I prefer, although I am not sure it is a
popular one. I think it's unreasonable to try to make an optional<T>
behave like a T, because it's not one. "*o" is a T; "o" isn't.

MO.

-- 
-Brian McNamara (lorgon_at_[hidden])

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