为什么 C++ 中的移动语义在函数签名 [duplicate] 中有右值引用

Why move semantics in C++ have rvalue reference in function signature [duplicate]

提问人:D.J. Elkind 提问时间:9/12/2023 更新时间:9/12/2023 访问量:82

问:

请考虑以下移动分配运算符:

class MyClass {
private:
  ssize_t buf_size;
  void* buf_ptr;
public:
  MyClass &operator=(MyClass &&rhs) {
    if (this != &rhs) {
      buf_size = rhs.buf_size;
      buf_ptr = rhs.buf_ptr;
      rhs.buf_ptr = nullptr;
      rhs.buf_size = -1;
    }
    return *this;
  }
}

是什么阻止我们使用而不是作为方法的签名?据我了解,如果是左值,则所有引用都应该有效。&operator=(MyClass &&rhs)&operator=(MyClass &rhs)rhsrhs

我可以看到一个问题:使用 makes copy assignment 运算符和移动赋值运算符看起来相同,我们无法确定要调用哪个运算符。但还有更深层次的原因吗?&operator=(MyClass &rhs)

C++ 移动语义 rvalue-reference

评论

0赞 BoP 9/12/2023
我们有一个auto_ptr类,它使用左值引用作为其移动构造函数(因为右值引用尚不可用)。事实证明这不是一个好主意,即使它在技术上是可行的。
0赞 Jan Schultke 9/12/2023
这个问题并不完全重复,但右值引用的动机和设计已经在许多其他问答中得到了解释。
0赞 Oersted 9/12/2023
您应该能够从临时性移动,这在左值引用签名中是不可能的。此外,对于大多数用户来说,移动普通对象可能是意想不到的。使用右值签名强制使用 std::move 移动左值对象。在这种情况下,这使得移动变得明确(而不是超越)。
0赞 Oersted 9/12/2023
您也可以以相反的方式阅读我的评论。您可以通过使用左值引用来实现移动语义,但这样,您将无法移动临时语义。您可能会使用户复制的对象失效,从而让您的用户感到惊讶。习惯于使用 std::move 的用户会惊讶地发现它没有编译。
0赞 Howard Hinnant 9/12/2023
我相信最初关于移动语义的提议中的一句话简洁地回答了这个问题:“拒绝使用复制语法从左值移动是move_ptr安全的关键。

答:

0赞 Sneftel 9/12/2023 #1

对于右值引用,没有比与左值引用不同的“更深层次的原因”了。自动确定引用是对左值还是右值,并执行正确的代码作为响应,是它们存在的全部原因。例如,不适用于采用左值引用的函数,因为临时值不是左值。myClass = MyClass{}