| Home | Libraries | People | FAQ | More

### 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();
    o.emplace(make_another_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`.