我是c ++ 11的新手,在阅读C++11 FAQ时遇到以下问题。
假设我们有一个函数f
()返回类型X
中的值,那么我们有以下方法来存储它返回的值:
X a = f(); // copy assignment
X&& b = f(); // move assignment
根据C++ FAQ,第二个避免了不必要的副本。
我的问题是:第二个总是接收函数调用返回值的首选方法吗?另外,auto c = f();
是否相当于上述任务之一?谢谢。
答案 0 :(得分:5)
您已错误地标记了这些行。它们都不是作业,更不用说分别复制和移动作业了。相反,第一个涉及复制/移动构造(取决于X
是否具有移动构造函数),第二个是简单地初始化引用。
接收函数调用返回值的首选方法是第一种方法:
X a = f();
f()
返回到对象a
的临时副本几乎肯定会被删除。这与auto c = f();
将采用的形式相同。
第二个应该很少(如果有的话)出现在您的代码中。您正在对f()
的返回类型进行右值引用。 Stroustrup只是为了证明temporaries可以绑定到rvalue引用。当您调用具有右值引用参数类型的移动构造函数/赋值运算符时,最常发生在实际代码中。
答案 1 :(得分:4)
你写的都不是作业。所有代码片段都声明并初始化一个新变量。
auto a = f()
与X a = f()
X && b
是一个参考,而不是一个对象。
始终创建一个本地对象变量,即X a = f()
,绝不是左值引用。 (几乎)从来没有一个充分的理由。在任何一种情况下,你都会得到一个与变量一样长的对象,并且不需要额外的复杂性。