|
Boost : |
From: Peter Dimov (pdimov_at_[hidden])
Date: 2002-12-12 07:41:12
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.
> > > 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.
> > > 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.
> Perhaps this could be called get_pointer() as shared_ptr<> does.
get_pointer() would be... less objectionable. :-)
> > 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.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk