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


Type requirements

The very minimum requirement of optional<T> is that T is a complete type and that it has a publicly accessible destructor. T doesn't even need to be constructible. You can use a very minimum interface:

optional<T> o;     // uninitialized
assert(o == none); // check if initialized
assert(!o);        //
o.value();         // always throws

But this is practically useless. In order for optional<T> to be able to do anything useful and offer all the spectrum of ways of accessing the contained value, T needs to have at least one accessible constructor. In that case you need to initialize the optional object with function emplace(), or if your compiler does not support it, resort to In-Place Factories:

optional<T> o;
o.emplace("T", "ctor", "params");

If T is MoveConstructible, optional<T> is also MoveConstructible and can be easily initialized from an rvalue of type T and be passed by value:

optional<T> o = make_T();
optional<T> p = optional<T>();

If T is CopyConstructible, optional<T> is also CopyConstructible and can be easily initialized from an lvalue of type T:

T v = make_T();
optional<T> o = v;
optional<T> p = o;

If T is not MoveAssignable, it is still possible to reset the value of optional<T> using function emplace():

optional<const T> o = make_T();

If T is Moveable (both MoveConstructible and MoveAssignable) then optional<T> is also Moveable and additionally can be constructed and assigned from an rvalue of type T.

Similarly, if T is Copyable (both CopyConstructible and CopyAssignable) then optional<T> is also Copyable and additionally can be constructed and assigned from an lvalue of type T.

T is not required to be DefaultConstructible.