Почему std :: option не разрешает присваивание перемещения для типов "перемещение конструкции и копирование только для назначения"? - PullRequest
1 голос
/ 18 марта 2019

Стандарт обязывает оператора присваивания перемещений 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:

  1. is_move_constructible_v<T> && is_move_assignable_v<T>
  2. is_move_constructible_v<T> && is_copy_assignable_v<T>

Где вторая форма может использовать назначение копирования, если bool(lhs) && bool(rhs), но перенести конструкцию, если !bool(lhs) && bool(rhs).

Я вижу довольно искусственную проблему с текущим набором предварительных условий в отношении следующих двух классов типов:

  1. Тип, который не может быть назначен для перемещения, но может быть назначен для копирования, может быть создан и перемещен и не может быть извлечен из построения перемещения при назначении, даже если создание является частью операции назначения. Будет выбран оператор присваивания optional, а конструктор копирования или копирование присваивают значение.

  2. Тип, который нельзя ни скопировать, ни назначить для перемещения, но переместить в конструкцию и назначить для копирования, вообще не может быть назначен.

Это то, что рассматривалось в процессе стандартизации для optional или есть какое-то обоснование, почему оно не было рассмотрено или было отменено?

(Отказ от ответственности: я знаю, что is_move_assignable обычно имеет значение true, если is_copy_assignable имеет значение true, если только оператор назначения перемещения явно не удален.)

1 Ответ

0 голосов
/ 15 июля 2019

Вам следует рассмотреть возможность использования std :: option :: emplace для типов, которые могут быть перемещены (второй случай)

...