当我们使用右值引用时,究竟会发生什么?std :: move如何工作?

Pra*_*ari 6 c++ rvalue-reference move-semantics c++11

我试图理解右值引用和移动语义.在下面的代码中,当我将10传递给Print函数时,它会调用rvalue reference overload,这是预期的.但究竟发生了什么,10将被复制(或从它引用的地方).其次,std::move究竟做了什么?它是从中提取值10 i然后通过它吗?或者是编译器使用右值参考的指令?

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;
}
Run Code Online (Sandbox Code Playgroud)

谢谢.

Rei*_*ica 9

在a的情况下,10可能会涉及优化,这将改变实际的实现,但从概念上讲,会发生以下情况:

  • int创建临时值并使用该值初始化10.

  • 该临时int值绑定到r值引用函数参数.

所以在概念上,没有复制 - 引用将引用临时.

至于std::move():可能有一些与引用等相关的棘手的位,但主要是,它只是一个转换为r值引用.std::move()没有实际移动任何东西.它只是将其参数转换为r值,以便可以从中移动.

无论如何,"移动"实际上并不是一个定义的操作.虽然考虑移动很方便,但重要的是l值与r值的区别.

"移动"通常由移动构造函数,移动赋值运算符和采用r值引用的函数(例如push_back())实现.正是他们的实现使得移动成为实际的移动 - 也就是说,它们被实现以便他们可以"窃取"r值的资源而不是复制它们.那是因为,作为一个r值,它将不再可访问(或者你保证编译器).

这就是为什么std::move()启用"移动" - 它将其参数转换为r值,信号,"嘿,编译器,我将不再使用这个l值,你可以让函数(如移动ctors)将其视为一个r值并从中偷走."


Mik*_*our 8

但究竟会发生什么,10将被复制(或从它引用的地方)

创建临时值,并将引用传递给函数.临时对象是右值,因此可以绑定到右值的引用; 所以选择了第二次过载.

其次什么std::move实际上做?

它为您提供了对其参数的右值引用.它等同于(根据定义)static_cast<T&&>.

尽管有这个名字,但它本身并没有任何动作; 它只是为您提供了一个可用于移动值的引用.