Самое минимальное требование необязательно <T>
заключается в том, что T
является полным типом и что он имеет общедоступный деструктор. T
не обязательно должен быть конструируемым. Вы можете использовать минимальный интерфейс:
optional<T> o;
assert(o == none);
assert(!o);
o.value();
Но это практически бесполезно. Для того, чтобы необязательно<T>
мог делать что-либо полезное и предлагать весь спектр способов доступа к содержащемуся значению, T
должен иметь по крайней мере один доступный конструктор. В этом случае вам необходимо инициализировать необязательный объект с функцией emplace()
, или если ваш компилятор не поддерживает его, прибегните к In-Place Factorys:
optional<T> o;
o.emplace("T", "ctor", "params");
Если T
MoveConstructible
, optional<T>
также MoveConstructible
и может быть легко инициализирован из r-значения типа T
и передан по значению:
optional<T> o = make_T();
optional<T> p = optional<T>();
Если T
CopyConstructible
, optional<T>
также CopyConstructible
и может быть легко инициализирован из значения l типа T
:
T v = make_T();
optional<T> o = v;
optional<T> p = o;
Если T
не является MoveAssignable
, все равно можно сбросить значение опционально<T>
с помощью функции emplace()
:
optional<const T> o = make_T();
o.emplace(make_another_T());
Если T
MoveConstructible
и MoveAssignable
, то optional<T>
также Moveable
и дополнительно может быть сконструирован и назначен из rзначения типа T
.
Аналогично, если T
является CopyableCopyConstructible
и CopyAssignable
, то optional<T>
также Copyable
и дополнительно может быть сконструирован и назначен из значения l типа T
.
T
не должно быть DefaultConstructible
.