【发布时间】:2019-11-14 10:15:00
【问题描述】:
正如许多其他帖子所解释的,将一个变量声明为右值引用并不保证它将调用移动赋值运算符,仅使用 std::move(即,转换为相同的右值引用) 会做的。例如:
struct A
{
A& operator=(A&& l_other) { std::cout << "move" << std::endl; }
A& operator=(A& l_other) { std::cout << "copy" << std::endl; }
};
A a;
// does not print anything, compiler does nothing here!
A&& b = std::move(a);
// prints "copy", not "move"
a = b;
// prints "move", but needs std::move()
a = std::move(b);
似乎将b 定义为A&& 在那一刻不会移动任何东西。之后,a = b 不会自动移动b,即使右侧部分被定义为A&&,正如其他帖子所解释的那样。我们需要显式调用std::move(b) 来移动b。
我的问题是,将变量定义为 A&& 有什么用处?我可以完美地将其定义为 A& 并将其移动完全相同。
【问题讨论】:
-
要解决为什么需要
std::move,请参阅std::move- 特别是注释中的这句话:“右值引用变量的名称是左值,必须转换将 xvalues 绑定到接受右值引用参数的函数重载”。是的,这很复杂:) -
@Victor 赋值
a = b触发复制赋值的原因是因为b 实际上是一个lvalue,类型为rvlaue reference to A。声明右值引用的原因是为了捕捉,嗯,右值,你不能用A&捕捉。 -
当您想与
A&区分开来时声明它们,即作为参数。我想不出在任何情况下您都希望A&&作为局部变量,而不是A或A & -
R 值引用(例如您的情况下的
A&&)很少在函数体中声明。它们主要用作函数参数。无论如何,一个简单的经验法则是任何有名字 (b) 的东西都是左值。 -
这可能会让你感兴趣:stackoverflow.com/q/45843974/2805305
标签: c++ move-semantics rvalue