这些是有效的移动和前进用法吗?
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
}
答案 0 :(得分:2)
将std::forward
与通用引用一起使用,即template <typename T> ... T&&
。
将std::move
与右值参考一起使用(例如A&&
)。
因此,f1
和f4
都是合理的解决方案。他们做不同的事情,所以你必须决定你想要哪一个。
请勿使用f2
或f3
。
答案 1 :(得分:2)
std::forward
存在是因为&&
在类型推导下的工作方式很奇怪。
在类型扣除下,T
中的T&&
将绑定到3种可能中的一种。如果从左值int&
推断,T
将绑定到int&
。然后int& &&
只是int&
。如果从左值int const&
推断,T
将绑定到int const&
,int const& &&
为int const&
。如果从某种价值int
推断出来,T
将绑定到int
,int&&
将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&&
这种类型非常模糊的可能性。我可能忽略了类型推导如何工作的一些细节,而rvalue
和lvalue
这些术语并没有完全反映完整的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。