Стандарт обязывает оператора присваивания перемещений optional
...
constexpr optional& operator=( optional&& other )
[...] не должны участвовать в разрешении перегрузки, если только
is_move_constructible_v<T>
верно и is_move_assignable_v<T>
верно.
Присвоение необязательного значения lhs = rhs;
делает либо
- уничтожить
lhs
(если bool(lhs) && !bool(rhs)
)
- конструкция
lhs
от rhs
(если !bool(lhs) && bool(rhs)
) или
- присвойте
rhs
lhs
(если bool(lhs) && bool(rhs)
).
Таким образом, было бы возможным иметь два набора предварительных условий для назначения хода: optional
:
is_move_constructible_v<T> && is_move_assignable_v<T>
is_move_constructible_v<T> && is_copy_assignable_v<T>
Где вторая форма может использовать назначение копирования, если bool(lhs) && bool(rhs)
, но перенести конструкцию, если !bool(lhs) && bool(rhs)
.
Я вижу довольно искусственную проблему с текущим набором предварительных условий в отношении следующих двух классов типов:
Тип, который не может быть назначен для перемещения, но может быть назначен для копирования, может быть создан и перемещен и не может быть извлечен из построения перемещения при назначении, даже если создание является частью операции назначения. Будет выбран оператор присваивания optional
, а конструктор копирования или копирование присваивают значение.
Тип, который нельзя ни скопировать, ни назначить для перемещения, но переместить в конструкцию и назначить для копирования, вообще не может быть назначен.
Это то, что рассматривалось в процессе стандартизации для optional
или есть какое-то обоснование, почему оно не было рассмотрено или было отменено?
(Отказ от ответственности: я знаю, что is_move_assignable
обычно имеет значение true, если is_copy_assignable
имеет значение true, если только оператор назначения перемещения явно не удален.)