标准在MoveAssignable的情况下对于自我移动赋值有何规定?

4
这是C++17关于MoveAssignable的当前描述: = rv;
如果t和rv不引用同一对象,则在赋值之前,t等同于rv的值,rv的状态未指定。注意:无论t和rv是否引用相同的对象,rv仍必须满足使用它的库组件的要求。这些要求中列出的操作必须按照规定工作,无论rv是否已被移动。对于“rv必须仍然满足使用它的库组件的要求”,这是指什么?
如果t和rv引用同一对象会怎样?在这种情况下,具有MoveAssignable的类型可以/应该做什么?
这个描述的意思是什么?
  1. 该库不会调用自身的移动赋值操作,因此该类型在这种情况下可以任意处理(甚至崩溃)。

  2. 或者该类型应该以某种方式处理此情况(不允许崩溃),但其结果并不重要。

  3. 或其他情况?

注意:在SO上有类似的问题,但是有互相矛盾/陈旧的答案和评论,因此我想澄清这一点。


3
无论当前标准如何,它应该说的是Eric Niebler在这里写的内容:http://ericniebler.com/2017/03/31/post-conditions-on-self-move/ 基本上,自移应该使对象保持在一个有效但未指定的状态。推理的方法是思考swap如何实现,并考虑允许自我交换。如果我没记错的话,当前的措辞会使自我移动成为未定义行为,因为弱化了右值引用不能创建非唯一别名的一般规则。 - Kerrek SB
1
相关问题在C++中,x = std::move(x)是否未定义? - Shafik Yaghmour
1个回答

2
“rv必须仍然符合使用它的库组件的要求”是什么意思?
这句话的含义是,即使rv的状态未指定,它也必须是有效的状态。例如,记录“我已离开!”状态并对随后的重新分配抛出异常的类型是不允许的,如果分配是必须支持的操作之一。
如果t和rv引用同一对象怎么办?
你已经引用了答案:“rv的状态未指定。”这与t是否引用相同的对象无关。
这个描述是什么意思:
2.或者类型应该以某种方式处理这种情况(不允许崩溃),但其结果并不重要。
是的,基本上就是这样。

谢谢您的回答!我找到了这个链接:http://eel.is/c++draft/res.on.arguments#1.3。其中写道:“如果函数参数绑定到一个右值引用参数,实现可以假设该参数是对该参数的唯一引用。”那么,标准库类型是否可以是可移动赋值的呢? - geza
唯一微妙且可能有些奇怪的问题是,“rv仍必须满足使用它的库组件的要求”为什么意味着什么?是否有标准的某个部分使这个句子具有这种含义? - geza
@geza 这是一条非规范性注释。从标准中没有任何迹象表明对移动后的对象进行有效操作可能会产生无效结果,可以推断出其含义。 - user743382
例如,std::sort 要求序列中的元素可比较,无论它们是否处于移动状态。 - Howard Hinnant
@HowardHinnant:你读懂了我的心思 :) 这就是我所做的,当我问这个问题时,我检查了std::sort的文档。然而,我没有发现任何额外的要求(除了Move*)。它在这里吗?http://eel.is/c++draft/sort#lib:sort还是其他地方? - geza
它属于[alg.sorting]分类。 - Howard Hinnant

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