----- Original Message -----
From: "William E. Kempf" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Tuesday, December 10, 2002 7:04 PM
Subject: Re: [boost] Formal review: Optional library

>
> Fernando Cacciola said:
>
> > But if I wrote:
> >
> > optional<int> x = foo();
> > if ( x )
> >   some(x);
> >
> > it really looked as if it were testing if 'x' is initialized
> > while it was acutally comparing the 'x' value against 0.
>
> I'm not sure I find this compelling.  Knowing that a test for
> initialization is done through optional::initialized(), I'd never mistake
> the if above for testing this.  This would cause problems only with
> someone unfamiliar with optional, but they are going to have problems no
> matter what interface you choose until they read the documentation.
>
... but I would make such mistakes, and I know too many people that would
also do it.

> > Eventually, I realized that value semantics are not really appropiate to
> > deal
> > with unininitialized states since it blurs the distinction between
> > testing against other values and testing whether it is initialized or
> > not. So I wonder which other semantics would deal with it properly,
> > and pointers poped into my mind quickly.
>
> But pointers are just the inverse of the problem above.  Test for validity
> is bald.

Only if safe_bool isn't used.
But, I'm just about to be convinced to added it, in which case,
test for validity will look just like it looks like
for any other smart/bare pointer.

>, while access to the "value" requires some supporting syntax (in
> this case, operator*).  This leaves users in the exact same scenario where
> a simple mistake leads to code that compiles but doesn't do what the
> programmer meant.

Can you give me an example of something that compiles but
doesn't do what the programmer meant?
Remeber that currently *opt=x is defined even if opt is uninitialized

> I think you're trying just a little too hard to make
> the interface "idiot proof".
>
Fair enough. I tend to do this, I know.
Maybe is becasue I use to work late at night, so I better protect myself
from myself :-))

> >> Now, assuming we stick with pointer semantics, let's make this as
> >> close to the "normal" smart pointer interface as possible:
> >>
> >> template <typename T>
> >> class optional
> >> {
> >> public:
> >>    optional();
> >>    explicit optional(T const& value);
> >>    optional(optional const& other);
> >>    template <typename U>
> >>       optional(optional<U> const& other);
> >>    ~optional();
> >>
> >>    T& operator*() const;
> >>    T* operator->() const;
> >>    T* get() const;
> >>    // T* release();
> >>    void reset();
> >>    void reset(T const& value);
> >>    operator unspecified-bool-type() const;
> >> };
> >>
> >>
> > This interface is greatly simplified mainly because
> > my interface offers deep-constantness:
> >
> > T const* peek() const ;
> > T*       peek();
> > T const& operator*() const;
> > prxy operator*() ;
> >
> > instead of:
> >
> > T* peek() const ;
> > T& operator*() const;
> >
> > The proxy is needed *only* to achieve deep-constantness.
> > If this feature weren't introduced, my interface would have looked just
> > like yours.
>
> I still don't see the need for the proxy.  The interface I gave could
> provide "deep-constantness" with out a proxy.  I'm not sure where I stand
> on whether or not optional<> should provide this, however.
>
Right. I mistakenly forgot what the proxy is for...
it has nothing to do with deep-constantness... o-)
it is required to support *opt=x for uninitialized optionals, which reset
'opt'
to initilized.

But wait....
I will have to discuss this feature (?) on its own, so I'll top post this
issue.

> >> Semantics and rationale:
> >>
> >> optional()
> >>
> >>    Constructs an "uninitialized" optional.
> >>
> >> explicit optional(T const& value)
> >>
> >>    Constructs an optional initialized to value through copy
> >> construction.
> >>
> >> optional(optional const& other)
> >>
> >>    Copy constructs an optional using the value-type's copy
> >> constructor.
> >>
> >> template <typename U> optional(optional<U> const& other)
> >>
> >>    Allows copy construction from "compatible" optionals (optionals
> >> with
> >> value types that can be used for constructing this optional's value
> >> type).  I'm not sure how important this one is for optional, to be
> >> honest.
> >>
> > I've never needed to convert between optinals.
> > On a related note, if deep-constantess is not supported
> > (as in your interface), an implicit conversion from
> > optional<T> to optional<T const> is needed because
> > the user will have to use <T const> to attach constantess
> > to the value.
>
> Actually, it's still not needed.
>
> optional<int> opt1(666);
> optional<const int> opt2(*opt1);
>
> Granted, it *IS* an important convenience, since you don't have to check
> the initialized state, but it's not strictly necessary.
?
Did you mean that conversion from <T> to <T const> can only be explicit?
Otherwise we said the same: there has to be a mechanism to convert from <T>
to <T const>

>
> >> ~optional()
> >>
> >>    If the optional is initialized, calls the value-type's destructor.
> >>
> >
> > Why isn't assignment supplied?
>
> Because I believe the reset is clearer, and safer.
>
I see.
We'll get back to this reset() issue on the post about: uninitialized
assignment
(doing *opt=x when opt is uninitialized)

Fernando Cacciola

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Reply via email to