Boost logo

Boost :

From: Fernando Cacciola (fcacciola_at_[hidden])
Date: 2001-09-03 15:47:03


----- Original Message -----
From: Douglas Gregor <gregod_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Friday, August 31, 2001 12:19 AM
Subject: Re: [boost] Re: optional vs variant vs any

> On Thursday 30 August 2001 06:38, you wrote:
> > > > Supporting direct initialization has the drawback that both
statements
> > > > below become equivalent, which I find confusing:
> > > >
> > > > optional<int> v ;
> > > >
> > > > v = 3 ;
> > > > *v = 4 ;
> > >
> > > I personally don't mind this equivalence. It's the same thing one
deals
> >
> > with
> >
> > > when using any or a variant type, except that instead of *v we have
> >
> > something
> >
> > > like any_cast<T>(v) or v.as<T>().
> >
> > Not quite so. AFAIK, any_cast<> and .as<> are rvalues.
>
> It's try that any_cast<> returns an rvalue, but .as<> returns an lvalue.
The
> definition could go either way, of course, but perhaps returning an rvalue
is
> safer because it guarantees type safety...
>
I see. But I still don't like the equivalence.

> > There is a problem, anyway, in supporting a non-explicit direct
> > initialization:
> >
> > optional<double> opt = foo();
> > if ( opt == 3.14 ) // This will automatically create a temporary for
the
> > 3.14, thus violating the strict pointer semantic I am trying to keep
> > strict.
>
> How is comparison between optional<T>s defined?
>
It is intentionally NOT DEFINED.
I've discussed this with Gennadiy (and I think he agreed).
The reason is that logical operations between optionals are actually
trivalued, that is: (optA == optB) could be true/false/undefined.
I purposedly rejected Gennaidy proposal of making operator == return false
if either operand is uninitialized.

You can compare optional *values* -as long as the proper operators are
defined in T- through dereferencing:

if ( *optA == *optB )

this way, the dereferencing takes care of possible uninitialized states so
the expression is truly boolean.

> > > > optional<int> v ( 3 ) ;
> > > > *v = 4 ;
> > >
> > > This might be a good compromise. It looks strange when you name v (why
> >
> > would
> >
> > > it be optional if you have a value for it?), but it's not quite so
> > > strange in a return statement.
> >
Agreed.

> > Perhaps I am biased by the coding style of having only one return
statatent
> > at the end. So direct initialization won't usually be of much help to me
in
> > a return statement.
> >
> > There is a situation, though, in which direct initialization is
> > *significantly* useful:
> >
> > void foo ( optional<point> where ) ;
> >
> > with direct initialization: foo ( optional<point>( point(2,3) ) ) ;
> >
> > currently: optional<point> p ; *p = point(2,3) ; foo(p);
>
> I'm not sure I understand why one would pass an optional parameter in this
> way,
How would you?
That is, assuming that you can't use point(0,0) as meaning 'I haven't gave
you any point', because the default action in case you don't pass the
optional point parameter is not to assume it is at the origin.

You may need to return a value but have no value to return; or you may need
to pass an argument, but have to argument to pass. These are two directions
for the same situation.
optional<> is intended to help with both.

> but if one does it then surely direct initialization would be a boon.
>
Agreed, and added, with a explicit constructor.

Fernando Cacciola
Sierra s.r.l.
fcacciola_at_[hidden]
www.gosierra.com


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