Boost logo

Boost :

From: Fernando Cacciola (fernando_cacciola_at_[hidden])
Date: 2002-12-11 15:01:12


Based on the coments made by reviewers, this is the new interface:

template<class T>
class optional
{
    optional () ;

    explicit optional ( T const& val ) ;

    optional ( optional const& rhs ) ;

    ~optional() ;

    // This is provided ONLY to allow implicit conversions from
    // optional<T> to optional<T const>.
    // It compiles only if remove_const<T>::type == U.
    template<class U> optional ( optional<U> const& non_const_rhs ) ;

    optional& operator= ( optional const& rhs ) ;

    void swap ( optional& rhs ) ;

    // Uninitializes the optional.
    void reset() ;

    // Initialied the optional (even if it was uninitialized)
    void reset ( T const& val ) ;

    T* get() const ;

    T* operator->() const ;

    T& operator *() const ;

    typedef T* (this_type::*unspecified_bool_type)();
    operator unspecified_bool_type() const ;

    bool operator!() const { return !m_initialized ; }

    // Disallow direct comparisons between optionals.
    friend void operator == ( this_type const&, this_type const& ) ;
    friend void operator != ( this_type const&, this_type const& ) ;
} ;

template<class T> inline T* get ( optional<T> const& opt ) ;

template<class T> inline void swap ( optional<T>& x, optional<T>& y ) ;

This interface settles two issues that were still open:

(1) deep-constantness:

I Followed David Abraham's suggestion and decoupled
constantness of the optional<> object with that of
the value being wrapped.
This is how pointers and most smart pointers work, so
the pointer semantic should suffice to explain this behaviour.

I did added a special template ctor which allows implicit
conversions from optional<T> to optional<T const>.

(2) Comparisons.
I'm still holding onto the decision to disallow direct comparison of
optional objects in favor of direction comparison of optional values:
That is, you cannot write:

if ( optA == optB )

and you have to write:

if ( *optA == *optB )

instead.

This is utterly important now that is has safe_bool,
because IMO, Tanton Gibbs interpretation is correct;
given safe_bool:

optional<int> opt0 ;
optional<int> opt1 ;

(opt0 == 0 ) // true
(opt1 == 0 ) // true

therefore....

(opt0 == opt1) HAS TO BE TRUE.

If the comparison above is properly understood,
that is, if it is clear that the initialized states
are being compared and not the values, then there is
no problem, but considering that:

optional<int> opt0(1);
optional<int> opt1(2);
(opt0 == opt1) // true

is also true even though the values are different,
I think that allowing direct comparions will
create unneccesary confusion.

If this interface is OK so far I'll update the code and the documention.

Q: Should I reflect this changes during the review?
 The new interface is somewhat different so it affect the rest of the
review.

Fernando Cacciola


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