概念
Assignable<LHS, RHS>指定由RHS指定的类型和值类别的表达式可以分配给由LHS指定类型的lvalue表达式。 给定的
lhs,引用对象lcopy的lvalue,例如
decltype((lhs))是LHS,rhs,decltype((rhs))是RHS这样的表达式,rcopy,一个与rhs相同的不同对象,只有在以下情况下Assignable<LHS, RHS>才会满意
std::addressof(lhs = rhs) == std::addressof(lcopy) (即赋值表达式产生一个与左操作数有关的lvalue );lhs = rhs后- `lhs` is equal to `rcopy`, unless `rhs` is a _non-const xvalue_ that refers to `lcopy` (i.e., the assignment is a self-move-assignment),
- if `rhs` is a _glvalue_: - If it is a _non-const xvalue_, the object to which it refers is in a valid but unspecified state;
- Otherwise, the object it refers to is not modified;
我对自我分配的笔记投了弃权票。
如果rhs指的是lcopy,则意味着lhs在赋值之前就等于rcopy (因为rhs和rcopy在前提条件下是相等的,lhs和rhs也是相等的,因为它们引用了同一个对象),那么在此之后,它也应该等于rcopy,因为没有进行赋值,因此,除非E 244注释完全多余,否则E 143是完全多余的,不是吗?
发布于 2019-07-21 01:32:44
只有在左操作数是lvalue和右操作数是rvalue并且都引用同一个对象时,才会出现自移动赋值条件。所以代码本质上是
x = std::move(x);可能通过其他中间引用或获取lvalue表达式的方法。
“除非”子句的意思是,当赋值是这种自我分配时,类型根本不需要满足任何要求。特别是,自我移动分配可能会修改所涉及的单个对象,甚至表现出未定义的行为.
这是可以的,因为在std::move或其他xvalue的普通使用中,这种可能性是不应该出现的。使用xvalue表达式意味着不再需要对象的旧值。因为左侧表达式引用的是同一个对象,这意味着我们也不关心它发生了什么。
在双方都使用相同变量(如x = std::move(x); )的实际代码将完全没有意义。一般情况下,xvalue不应该传递给函数,除非有充分的理由知道对象不会通过其他方式被访问(至少在对象的状态重要的情况下),直到对象被赋予一个新的特定状态(如果有的话)--例如,不知道存在对象的其他引用、指针、迭代器等,否则以前提供给对象的代码将不再以涉及访问对象的方式使用。在标准库中,通常对rvalue的保证是[res.on.arguments]/1.3的一个原因:当调用库函数时,“如果函数参数绑定到rvalue引用参数,则实现可能假定此参数是对此参数的唯一引用”。
在相关的说明中,一些类提供了更具体的移出对象状态的保证,而不仅仅是一般的“未指定但有效”状态。类可以保证移动对象在移动构造函数或移动赋值之后始终为空。但是请注意,如果允许使用x = std::move(x),则不能保证左侧现在具有以前的右边值,而右侧现在是空的!
https://stackoverflow.com/questions/57129460
复制相似问题