Boost logo

Boost :

From: Fernando Cacciola (fernando_cacciola_at_[hidden])
Date: 2003-09-01 12:30:54


Joel de Guzman <djowel_at_[hidden]> wrote in message
news:003401c36fd9$9a38b5a0$64646464_at_godzilla...
> Daniel Frey <daniel.frey_at_[hidden]> wrote:
> > Joel de Guzman wrote:
> >> Although I don't see this as problematic:
> >>
> >> optional<int> x;
> >> if (x)
> >> foo(x);
> >>
> >> Or perhaps:
> >>
> >> optional<int> x;
> >> if (!!x)
> >> foo(x);
> >>
> >> We already have an implicit conversion to safe_bool and an
> >> operator ! anyway. Keep it. There's nothing wrong with it:
> >>
> >> operator unspecified-bool-type() const;
> >> bool operator!() const;
> >
> > IMHO, there is something terribly wrong here because now optional<T> has
> > two interfaces. The interface of optional itself and the interface of T.
> > If you think that optional<T> can be used like T (having the
> > value-interface), you are immediately fooled by if(x) as it doesn't
> > check T's value. A pointer-interface is much cleaner as it gives the
> > user a hint that he is using a wrapper and in practice, I always prefer
> > to be a little more explicit on these things (even at the cost of an
> > occasional * here and there) than to have silent bugs.
>
> If you really want it to be explicit, the first version, which I prefer
> (and you snipped ;-) is so much better:
>
> optional<int> x;
> if (x != none)
> foo(x);
>
>
safe_bool conversion wasn't part of the original submision.
I was against it for the reasons you give, but at some point I
was conviced that the expressive power of the highly idiomatic
implicit boolean evaluation was worth it.
So many objects provide boolean evaluation through implicit
conversion that it is nowaday the most common interface for
this operation.

> Who's fooling who? You said 2 interfaces, the current optional<T> is
> actually the one with the 2 interfaces. In some ways, it has a value
> interface (construction, reset , ==, !=) and pointer interface on some
> (*, ->, get).
>
What's wrong operators * and ->?
Iterators use them, and they're not pointers.

If the problem is that it makes optional<> appear as a pointer,
then it is the documentation job to avoid it.

>
> What I am trying very hard to say is to stick to only *ONE* interface
> and one concept.
>
How does the presence of operator* and -> makes two interfaces?

optional<> has only one interface and one concept.

It just happen to use the ubiquitous * and -> syntax to express
the same notion that is expressed through those operators when they're
used with pointers and iterators, but this doesn't mean that
optional<> pretends to be a pointer or an iterator.

> Syntactically, there's nothing inherently wrong with:
>
> if (x)
> foo(x);
>
> We see it all the time with ints:
>
> int x;
> if (x)
> foo(x);
>
> Yet, I have to admit that after thinking about it some more, I realized
> an ambiguity when T is bool. Example:
>
> optional<bool> x;
> if (x)
> foo(x);
>
> That is why I really prefer the more explicit syntax:
>
> optional<int> x;
> if (x != none)
> foo(x);
>
>
Implicit safe_bool was supported becasue it is extremely idiomatic.

> A small price to pay, considering the advantages. 1) Unification of
> the optional and variant where optional<T> <--> variant<T, none_t>.

variant doesn't support implicit conversion to any of its bounded types.
It does support implicit construction and direct assignment, as I've
proposed for optional at my first post in this thread.

variant<> has get() as a value accessor.
optional<> has operator*() with the same semantic
(forget about optional's get() now)

> 2) Only one underlying semantics (value-semantics) as opposed to
> (sometimes value, sometimes pointer semantics)

There is just one underlying semantic in optional: value semantics.

> and 3) Plays well
> with generic code (I'll give another use-case in addition to Mat's).
>
This can be addressed by fixing optional::get() to return a reference
instead of a pointer.
(more on this on another post)

Fernando Cacciola


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