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

4

标准规定了 optional 的移动赋值运算符必须...

constexpr optional& operator=( optional&& other )

只有当is_move_constructible_v 为true且is_move_assignable_v 为true时,才能参与过载解析。
可选值的赋值lhs = rhs; 要么销毁lhs(如果bool(lhs)&&!bool(rhs)),要么从rhs构造lhs(如果!bool(lhs)&& bool(rhs)),或将rhs分配给lhs(如果bool(lhs)&& bool(rhs))。
因此,移动可选项的赋值可能有两组前提条件:
1. is_move_constructible_v && is_move_assignable_v 2. is_move_constructible_v && is_copy_assignable_v 第二种形式可以使用复制赋值(如果bool(lhs)&& bool(rhs)),但是如果!bool(lhs)&& bool(rhs),则进行移动构造。
我认为当前的前提条件在以下两类类型方面存在明显的人为问题:
1. 既不可移动赋值也可复制赋值,移动构造和复制构造可行的类型不能从赋值的移动构造中受益。 将选择optional的复制赋值运算符并复制构造或复制分配该值。 2. 既不可复制构造也不可移动赋值,但可移动构造和可复制赋值的类型根本无法分配。
这是否在optional的标准化过程中被考虑过,或者是否有任何理由未被考虑或已被放弃?
(免责声明:我知道如果显式删除移动赋值运算符,则is_move_assignable通常为true。)

3
如果类型T是可移动构造的(is_move_constructible_v<T>),并且也可以移动赋值(is_move_assignable_v<T>),那么式子"is_move_constructible_v<T> && is_move_assignable_v<T> == is_move_constructible_v<T> && is_copy_assignable_v<T>"就不再需要了。正如这里所示,即使移动赋值运算符被隐式地删除了,只要复制赋值运算符没有被删除,则仍然可以进行移动赋值。 - NathanOliver
1
为什么您会明确删除移动操作,但允许复制? - NathanOliver
4
如果问题像你承认的那样是人为制造出来的,那么让标准增加强制库实现者有时使用复制赋值运算符而不是移动赋值运算符来增加工作量就没有意义。同样地,将这个要求编入标准会使标准变得更加复杂。 - Brian Bi
5
如果您有一种类型是可复制构造和赋值但不可移动构造和赋值,那么您正在做一些非常奇怪的事情,我不确定为了支持这样的东西而复杂化库是否值得。 - Barry
1
一般来说,库对可复制但不可移动的异常情况并不关心。 - T.C.
显示剩余5条评论
1个回答

5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接