Boost logo

Boost :

From: Fernando Cacciola (fernando_cacciola_at_[hidden])
Date: 2002-12-12 09:45:21


----- Original Message -----
From: "Peter Dimov" <pdimov_at_[hidden]>
To: "Boost mailing list" <boost_at_[hidden]>
Sent: Thursday, December 12, 2002 9:41 AM
Subject: Re: [boost] Formal review: Optional library

> From: "Fernando Cacciola" <fernando_cacciola_at_[hidden]>
> >
> > Let me check if I followed your logic:
> >
> > optional<T> opt(v) does a 'copy' of the 'v'; it does not hold onto the
> > 'v' itself as if it were given a handle. So it clearly has deep copy
> > semantics.
> > Your argument is that since it has deep copy semantics, it should have
> > deep-constantness
> > too, right?
>
> Right.
>
> "Pointer semantics" means that copies of the pointer refer to the same
> object. This is clearly not the case with optional<> as it contains a
value,
> it doesn't merely point to one. Optional simply does not have pointer
> semantics. It provides a pointer-like interface which may be controversial
> but I'm not convinced that better alternatives exist.
>
This is correct.
See my response to Augustus where I realize that optional<> mixes value and
pointer
semantics on two different parts of the interface.
As I argumented there, in spite of the oddity, the separation is made in
such a way that
there is no -or little- confusion (once you get how it is)

>
> > > > void swap ( optional& rhs ) ;
> > >
> > > Doesn't the standard std::swap do the job, by the way?
> > >
> > With the current implementation, yes, it does.
> > But if optional<> is eventually changed to use an implementation
> > with stronger exception guarantees, wouldn't it require a member swap()?
>
> Yes, I thought about that, too. But if the current swap semantics are
> retained, it should simply be removed. Otherwise optional<T>::swap must
> offer at least swap(T&, T&)'s guarantee.
>
I'm not sure I follow.
What are swap(T&, T&) guarantees in general?
I thought this depended on the specific type.

>
> > > > template<class T> inline T* get ( optional<T> const& opt ) ;
> > >
> > > Why the free function?
> > >
> > On the user code I **really** prefer to write: get(opt) instead of
> opt.get()
> > becasue I like to decouple from class types as much as possible.
>
> Free functions with generic names should be avoided.
>
I agree.

> > Perhaps this could be called get_pointer() as shared_ptr<> does.
>
> get_pointer() would be... less objectionable. :-)
>
This particular free function is precisely intended to decouple this
functionality (get a pointer that points to the value) from the class type
(optional<> in this case); so it makes sense to be a commonly named free
function.
But then, get_pointer() is the common name, so it has to be that one.

> > > I think that the comparisons we were discussing as a possible
candidate
> > > required both the initialized states and the held values to match.
> > >
> > > This is consistent with the "optional as a container of zero/one" and
> the
> > > "optional as a value with an additional unitialized state" models.
> > >
> > I don't follow 'exactly'
> > Can you elaborate?
>
> bool operator==(optional const & a, optional const & b)
> {
> if(a.initialized() != b.initialized()) return false;
> return a.initialized()? *a == *b: true;
> }
>
> That is, an unitialized optional is equal to an unitialized optional, and
> not equal to an initialized one.
>
> Two initialized optionals are equal when their values compare equal.
>
> If you think of an optional as a constrained std::vector<T>, you'll see
that
> the above semantics correspond to vector<>::operator==.
>
> The other way of thinking about an optional<T> is that it is capable of
> storing all possible values of type T plus an additional value
corresponding
> to the uninitialized state. In other words, optional<int> can be thought
of
> as an integer that can store INT_MIN...INT_MAX+1, with INT_MAX+1 being
> interpreted as uninitialized. The above comparison does the right thing
for
> this model, too.
>
> A variant<T, nil_t> would have the same operator==, too.
>
Well, this is exactly what William suggested.
Still I don't like it.
But thanks to William insistance on a sound rationale, I realize now that
the real problem
is not the personally-odd definition that something is definitely not equal
to nothing
(instead of undefined); since this definition doesn't look odd to many of
you,
but the fact that such definition would look ackward with respect to
the pointer-like interface.

Anyway, as I posted recently, I'm just about to conclude that relational
operators
could be properly defined as a synonim for: get_pointer(o1) .relop.
get_pointer(o2).
I found this definition totally consistent with pointer semantics and the
implied
aliasings.

Fernando Cacciola


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