为什么 std::Optional 不允许“仅移动构造和复制分配”类型的移动分配?

Pix*_*ist 4 c++ move-semantics c++17 stdoptional

该标准要求移动赋值运算符optional...

constexpr optional& operator=( optional&& other )
Run Code Online (Sandbox Code Playgroud)

[...] 不得参与重载决策,除非 is_move_constructible_v<T>为真并且is_move_assignable_v<T>为真。

可选值的分配lhs = rhs;可以执行以下任一操作:

  • 摧毁lhs(如果bool(lhs) && !bool(rhs)
  • lhs( rhsif !bool(lhs) && bool(rhs)) 或
  • 分配rhslhs(如果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>

其中第二种形式可以使用复制赋值 if ,bool(lhs) && bool(rhs)但移动构造 if !bool(lhs) && bool(rhs)

对于以下两类类型,我认为当前的先决条件集存在一个不可否认的相当人为的问题:

  1. 不可移动赋值但可复制赋值、可移动构造和可复制构造的类型不能从赋值时的移动构造中受益,即使构造是赋值操作的一部分。将选择复制赋值运算optional符并复制构造或复制赋值。

  2. 既不可复制构造也不可移动分配但可移动构造且可复制分配的类型根本无法分配。

在标准化过程中是否已经考虑过这一点,optional或者是否有任何理由说明为什么没有考虑或已放弃这一点?

(免责声明:我知道如果is_move_assignable为真,则通常is_copy_assignable为真,除非移动赋值运算符被显式删除。)

cos*_*cos 5

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