C++ std::move 的一些问题

发布时间 2023-06-20 11:47:51作者: strive-sun

看 SO 上有一个比较奇怪的问题,

问题代码:

ClassX c = std::move(object_c);  // Invokes move constructor

ClassX&& cr = std::move(object_c);
ClassX c = cr;  // Invokes copy constructor

题主的疑问:cr 是右值了,为什么 `ClassX c = cr` 会触发拷贝构造,而不是移动构造

对此的解释:

If it has a name, it's an lvalue. cr is a name, it's an lvalue. 

the code should do ClassX c = std::move(cr);. Keep in mind that std::move does not itself move anything, it only allows a move to occur as-if the variable were an unnamed temporary (such as a return value or result of an expression). It also allows a variable to be bound to an rvalue reference (usually something that is useful for parameter passing). If you find this to be confusing, you are not alone; it is confusing.  

我测试的 demo:

#include <iostream>

class A {
 public:
  A() { std::cout << "Constructors" << std::endl; }

  A(const A& a) { std::cout << "Copy Constructors" << std::endl; }

  A& operator=(const A& a) {
    std::cout << "Assignment Operators" << std::endl;

    return *this;
  }

  A& operator=(const A&& a) {
    std::cout << "Move Assignment Operators" << std::endl;
    return *this;
  }
};

int main() {
  A a;    // Constructors
  A a_5;  // Constructors
  A a_6;  // Constructors

  A&& a_1 = std::move(a);  // 没有提示
  A& a_2 = a;              // 没有提示

  A a_7 = a_1;           // Copy Constructors
  A a_3 = a;             // Copy Constructors
  A a_4(a);              // Copy Constructors
  A a_8 = std::move(a);  // Copy Constructors

  a_6 = a_1;  // Assignment Operators
  a_5 = a;    // Assignment Operators
  a_1 = a_8;  // Assignment Operators

  a_6 = std::move(a_1);  // Move Assignment Operators

  return 0;
}