Эта библиотека предполагает, что деструктор<T>не выбрасывает исключений. Если это так, то поведение многих операций на<optional<T>>не определено.
Следующие мутирующие операции никогда не делают исключений:
- <
optional<T>::operator=(none_t
)noexcept>
- <
optional<T>::reset()noexcept>
Кроме того, следующие конструкторы и деструктор никогда не выбрасывают исключения:
- <
optional<T>::optional()
noexcept>
- <
optional<T>::optional(
none_t)
noexcept>
Что касается следующих функций назначения:
- <
optional<T>::operator=(optional<T>const&)>
- <
optional<T>::operator=(Tconst&)>
- <
template<classU>optional<T>::operator=(optional<U>const&)>
- <
template<classInPlaceFactory>optional<T>::operator=(InPlaceFactory
const&
)>
- <
template<classTypedInPlaceFactory>optional<T>::operator=(TypedInPlaceFactory
const&
)>
- <
optional<T>::reset(Tconst&)>
Они направляют вызовы соответствующим строителям или заданиям<T>(в зависимости от того, инициализирован ли факультативный объект или нет); поэтому, если конструктор<T>и назначение обеспечивают сильную гарантию безопасности исключения,<optional<T>>назначение также обеспечивает сильную гарантию безопасности исключения; в противном случае мы получаем только базовую гарантию. Кроме того, если оба участвуют<T>конструктор и назначение никогда не бросать,<optional<T>>назначение также никогда не бросает.
Если только<T>строитель или назначение бросает, назначения<optional<T>>не бросать ничего другого самостоятельно. Бросок при назначении никогда не изменяет состояние инициализации любого необязательного объекта:
optional<T> opt1(val1);
optional<T> opt2(val2);
assert(opt1);
assert(opt2);
try
{
opt1 = opt2;
}
catch(...)
{
assert(opt1);
assert(opt2);
}
Это также относится к передвижению заданий/конструкторов. Тем не менее, операции перемещения делаются без броска чаще.
Операция<emplace>обеспечивает основные гарантии безопасности. Если он бросает, необязательный объект становится неинициализированным независимо от его начального состояния, а его предыдущее содержащееся значение (если таковое имеется) разрушается. Он не вызывает никакого назначения или перемещения / копирования конструктора<T>.
Если<swap>на опциональном не настроен, его первичная реализация пересылает вызовы<T>'s<swap>или конструктору перемещения (в зависимости от состояния инициализации факультативных объектов). Таким образом, если и<T><swap>и движущийся конструктор никогда не бросают,<swap>на<optional<T>>никогда не бросает. Точно так же, если и<T><swap>, и движущийся конструктор предлагают сильную гарантию,<swap>на<optional<T>>также предлагает сильную гарантию.
В случае, если<swap>опционально настроен, вызов к<T>конструктору хода заменяется вызовами к<T>конструктору по умолчанию, за которым следует<swap>. (Это более полезно для старых компиляторов, которые не поддерживают семантику движения, когда вы хотите получить более сильные гарантии безопасности исключения.) В этом случае исключительные гарантии безопасности для<swap>зависят от гарантий<T>'s<swap>и конструктора по умолчанию.