Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Exception Safety Guarantees

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

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:

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