Boost logo

Boost :

From: Fernando Cacciola (fernando_cacciola_at_[hidden])
Date: 2002-11-22 15:32:41

----- Original Message -----
From: "Rozental, Gennadiy" <gennadiy.rozental_at_[hidden]>
To: "'Boost mailing list'" <boost_at_[hidden]>
Sent: Friday, November 22, 2002 4:14 PM
Subject: RE: [boost] Re: Formal Review Request: class optional<>

> > Good point. On a few ocasions I have use optional<> to pass optional
> > parameters.
> > However, I've came to the following:
> >
> > Take you example for instance:
> >
> > void fn(int iImportant, optional<int> iNotImportant = optional<int>())
> > {
> > if ( !!iNotImportant )
> > {
> > // not important argument recieved, use it.
> > foo ( * iNotImportant ) ;
> > }
> > }
> >
> > Since optional<> uses pointer semantics, the above code could
> > have been
> > written using a true pointer with nearly the same syntatic
> > usage of the
> > optional parameter:
> >
> > void fn(int iImportant, int* iNotImportant = NULL )
> > {
> > if ( !!iNotImportant )
> > {
> > // not important argument recieved, use it.
> > foo ( * iNotImportant ) ;
> > }
> > }
> We already talked about this: pointer will add extra memory access,
> should not (in fact it should be inlined and won't be different from by
> value parameter)
You are mis-remembering our previous talk.
One thing is the pointer 'semantic' of optional<>, and another is its
internal representation.
Back then I agreed that for some types the internal representation can use a
copy by-value, so no extra indirection is used to access it. This is
currently the case, except that the descicion is no longer made by the user:
if the type T has trivial default ctor, copy ctor, assignment and destructor
(such as a POD), the value-based implementation is used.

As you might recall, the pointer-based implementation allows optional<T> to
remove the default-constructible requirement on T. You can be sure that
imposing this requirement would rule out optional<> of many uses, I know
this as a fact since I use it extensively with types which do not have
default constructors.

As for the reasons for pointer 'semantics' (the optional interface), please
go back to our extensive discussions about it. You finally agreed with me in
that the *interface* requires this semantic in order to consistently deal
with the uninitialized case.

> > The constructor must be explicit in order to disable
> > unexpected implicit
> > conversions.
> Some may still prefer sometime
> foo(3)
> to
> foo(&lvalue(3));
> foo(optional<T>(3));
I also prefer the former of course, but the point is that it can only be
allowed at the expense of other things I do not prefer, and some -if not
most- would not prefer either.
I've played in real projects most of the other alternatives that come to
mind, and only the current one (pointer semantics) was consistent enough to
allow for extensive usage without nasty subtleties.

> implicit conversion to optional should not be dangerous anyway.
I disagree.
Implicit conversions are usually problematic, but with optional<>, it is
even worst, since
(1) a conversion from an uninitialized optional is undefined
(2) the distinction between
     (a) the operation of testing whether an optional is initialized or not
     (b) the operation of accesing the optional value (in this case via a
blurs, and the code doing any of the above quickly tends to read ambiguous.

I know this from experience: Earlier versions of optional<> (named
stateful_t then), years before I present it to boost, allowed implicit
conversions, but it was a mistake that casued me too much wasted time. After
I adopted pointer semantics, I've never again run into a bug introduced as a
result of subtle semantics.

> > The reason why you can't have optional<T&> is -at least- that
> > you cannot
> > have a reference to a reference,
> > and optional<T> uses "T {const} &" (for example, in the constructor).
> use add_reference instead?
Maybe, but actually, I don't think optional<> should work with references.
It is supposed to wrap a 'value', not a reference/pointer.

Fernando Cacciola

Boost list run by bdawes at, gregod at, cpdaniel at, john at