为什么std :: optional不允许对“仅移动构造和复制分配”类型进行移动分配?

时间:2019-03-18 20:49:06

标签: c++ c++17 move-semantics stdoptional

标准要求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 :(得分:0)

对于可移动构造的类型(第二种情况),您应该考虑使用std::optional::emplace