7

我试图理解右值引用和移动语义。在下面的代码中,当我将10传递给Print函数时,它调用了预期的rvalue引用重载。但究竟发生了什么,这10个将被复制到哪里(或从哪里引用)。其次是什么标准::移动真的吗?它是否从中提取值10然后通过?还是编译器使用rvalue引用的指令?

无效打印(int&i){cout<<“L值参考”<<endl;}无效打印(int&&i){cout<<“R值参考”<<endl;}整型main(){整数i=10;打印(i)//好的,可以理解打印(10)//10不会被复制吗?那么它将存储在哪里打印(标准::移动(i))//运动到底是做什么的返回0;}

谢谢。

1

3个答案

重置为默认值
9

但究竟发生了什么,这10个将被复制到哪里(或从哪里引用)

将创建一个临时值,并将引用传递给函数。临时项目包括右旋,因此可以绑定到维瓦卢参考文献;所以选择了第二个过载。

其次是什么标准::移动真的吗?

它给你一个维瓦卢引用其论点。根据定义,它相当于static_cast<T&>.

尽管有这个名字,但它本身并没有任何动作;它只是给你一个可以用来移动值的引用。

9

如果是10,可能会涉及到一些优化,这些优化将改变实际的实现,但从概念上讲,会发生以下情况:

  • A临时整数创建并用值初始化10.

  • 那个临时的整数绑定到r值引用函数参数。

因此,从概念上讲,没有复制-引用将引用临时的。

至于标准::移动():可能会有一些与引用等相关的棘手问题,但主要是,它只是一个转换为r值的引用。标准::移动()事实上移动任何东西。它只是把它的参数变成一个r值,这样它就可以从中移动。

无论如何,“移动”并不是一个定义好的操作。虽然考虑移动很方便,但重要的是l值与r值的区别。

“Moving”通常由move构造函数、move赋值运算符和采用r值引用的函数(例如推送(_back)). 正是它们的实现使移动成为实际的移动,也就是说,它们的实现是为了“窃取”r值的资源,而不是复制它们。这是因为,作为一个r值,它将不再是可访问的(或者您向编译器承诺是这样的)。

这就是为什么标准::移动()启用“移动”-它将其参数转换为r值,发出信号,“嘿,编译器,我不会再使用这个l值了,你可以让函数(如move ctors)将其视为r值并从中窃取。”

2
  • 1
    那个临时变量意味着无名对象? 评论 2013年10月1日6:18
  • @praitkothari我从没说过是暂时的变量。这将是暂时的对象类型为整数是的,它将是无名的。 评论 2013年10月1日6:21
-1

标准::移动铸造整数在里面整数&&通过static_cast<int&&>.最终,如果类型是或a结构,如果定义了移动构造函数(隐式或显式),则将调用该构造函数,而不是复制构造函数/经典构造函数.

1
  • 2
    好的,我的问题回答了一半。。,因为我仍然不知道如果我将值作为rvalue-ref传递会发生什么 评论 2013年10月1日6:15

不是你想要的答案吗?浏览标记的其他问题问你自己的问题.