Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

Exception Safety Guarantees
PrevUpHomeNext

Because of the current implementation (see Implementation Notes), all of the assignment methods:

  • optional<T>::operator= ( optional<T> const& )
  • optional<T>::operator= ( T const& )
  • template<class U> optional<T>::operator= ( optional<U> const& )
  • template<class InPlaceFactory> optional<T>::operator= ( InPlaceFactory const& )
  • template<class TypedInPlaceFactory> optional<T>::operator= ( TypedInPlaceFactory const& )
  • optional<T>:::reset ( T const&)

Can only guarantee the basic exception safety: The lvalue optional is left uninitialized if an exception is thrown (any previous value is first destroyed using T::~T())

On the other hand, the uninitializing methods:

  • optional<T>::operator= ( detail::none_t )
  • optional<T>::reset()

Provide the no-throw guarantee (assuming a no-throw T::~T())

However, since optional<> itself doesn't throw any exceptions, the only source for exceptions here are T's constructor, so if you know the exception guarantees for T::T ( T const& ), you know that optional's assignment and reset has the same guarantees.

//
// Case 1: Exception thrown during assignment.
//
T v0(123);
optional<T> opt0(v0);
try
{
    T v1(456);
    optional<T> opt1(v1);
    opt0 = opt1 ;

    // If no exception was thrown, assignment succeeded.
    assert( *opt0 == v1 ) ;
}
catch(...)
{
    // If any exception was thrown, 'opt0' is reset to uninitialized.
    assert( !opt0 ) ;
}

//
// Case 2: Exception thrown during reset(v)
//
T v0(123);
optional<T> opt(v0);
try
{
    T v1(456);
    opt.reset ( v1 ) ;

    // If no exception was thrown, reset succeeded.
    assert( *opt == v1 ) ;
}
catch(...)
{
    // If any exception was thrown, 'opt' is reset to uninitialized.
    assert( !opt ) ;
}

Swap

void swap( optional<T>&, optional<T>& ) has the same exception guarantee as swap(T&,T&) when both optionals are initialized. If only one of the optionals is initialized, it gives the same basic exception guarantee as optional<T>::reset( T const& ) (since optional<T>::reset() doesn't throw). If none of the optionals is initialized, it has no-throw guarantee since it is a no-op.


PrevUpHomeNext