我正在尝试理解右值引用和 move 语义。在下面的代码中,当我将 10 传递给 Print 函数时,它会调用右值引用重载,这是预期的。但到底发生了什么,这 10 个将被复制到哪里(或从它引用的地方)。其次,std::move
实际上做了什么?它是否从 i
中提取值 10 然后传递给它?或者它是编译器使用右值引用的指令?
void Print(int& i)
{
cout<<"L Value reference "<<endl;
}
void Print(int&& i)
{
cout<<"R Value reference "<< endl;
}
int main()
{
int i = 10;
Print(i); //OK, understandable
Print(10); //will 10 is not getting copied? So where it will stored
Print(std::move(i)); //what does move exactly do
return 0;
}
谢谢。
最佳答案
在 10
的情况下,可能会涉及优化,这将改变实际的实现,但从概念上讲,会发生以下情况:
创建临时
int
并使用值10
进行初始化。临时
int
绑定(bind)到右值引用函数参数。
所以从概念上讲,没有复制 - 引用将引用临时的。
至于 std::move()
:可能有一些与引用等相关的棘手位,但主要是,它只是对右值引用的强制转换。 std::move()
不实际上 move 任何东西。它只是将其参数转换为右值,以便可以将其移出。
无论如何,“move ”并不是真正定义的操作。虽然考虑 move 很方便,但重要的是左值与右值的区别。
“move ”通常由 move 构造函数、 move 赋值运算符和采用右值引用的函数(例如 push_back()
)实现。正是它们的实现使 move 成为实际 move ——也就是说,它们的实现使得它们可以“窃取”r 值的资源而不是复制它们。那是因为,作为右值,它将不再可访问(或者您向编译器 promise )。
这就是 std::move()
启用“move ”的原因 - 它将其参数转换为右值,发出信号,“嘿,编译器,我不会使用这个左值此外,您可以让函数(例如 move ctors)将其视为 r 值并从中窃取。”
关于c++ - 当我们使用右值引用时到底发生了什么,std::move 是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19109079/