前进或移动

时间:2013-04-15 11:53:20

标签: c++ c++11 move-semantics rvalue-reference

这些是有效的移动和前进用法吗?
f3和f4是一样的吗?
这样做有危险吗?
谢谢!

#include <utility>
class A {};
A f1() {
  A a;
  return a;   // Move constructor is called
}
A f2(A&& a) {
  return a;   // Copy constructor is called, which is what I try to avoid.
}
A f3(A&& a) {
  return std::forward<A&&>(a); // Move constructor is called
}
A f4(A&& a) {
  return std::move(a); // Move constructor is called
}

3 个答案:

答案 0 :(得分:2)

  • std::forward通用引用一起使用,即template <typename T> ... T&&

  • std::move右值参考一起使用(例如A&&)。

因此,f1f4都是合理的解决方案。他们做不同的事情,所以你必须决定你想要哪一个。

请勿使用f2f3

答案 1 :(得分:2)

std::forward存在是因为&&在类型推导下的工作方式很奇怪。

在类型扣除下,T中的T&&将绑定到3种可能中的一种。如果从左值int&推断,T将绑定到int&。然后int& &&只是int&。如果从左值int const&推断,T将绑定到int const&int const& &&int const&。如果从某种价值int推断出来,T将绑定到intint&&int&&。{/ p>

std::forward是一个用于反转该地图的效用函数。 std::forward<>的三个相关签名是:T& std::forward<T&>(T&)T const& std::forward<T const&>(T const&)T&& std::forward<T>(T&&)

所有这一切在使用称为“完美转发”的技术时非常有用,您在类型推导上下文中使用T&&t,然后std::forward<T>(t)传递“相同类型”正如从另一个电话中推断的那样。

请注意,上面有一些简化的谎言。作为一个例子,还有T const&&这种类型非常模糊的可能性。我可能忽略了类型推导如何工作的一些细节,而rvaluelvalue这些术语并没有完全反映完整的5倍(或者是6?)不同类型的变量值C ++ 11

答案 2 :(得分:1)

对于您的示例,他们会做同样的事情,但使用std::move

是惯用的
A f(A&& a) {
  // use std::move(a)
}

与功能模板

略有不同
template<typename A>
A f(A&& a) {
   // use std::forward<A>(a)
}

不同之处在于第二个版本可以同时接收左值和右值(Scott Meyers将它们命名为“universal references”),而第一个版本只能接收rvalues。