前进或移动
Forward or Move
这些是move和forward的有效用法吗?
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
}
std::forward
的存在是因为&&
在类型演绎下的工作方式有一个奇怪的现象
在类型演绎下,T&&
中的T
将绑定到3种可能性之一。如果从左值int&
推导,则T
将绑定到int&
。那么int& &&
就是int&
。如果从左值int const&
推导出来,T
将绑定到int const&
, int const& &&
是int const&
。如果由某种右值int
导出,则T
将绑定到int
,并且int&&
是int&&
。
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
并没有完全反映c++ 11中5倍(或者6倍?)不同类型的变量值。
-
使用
std::forward
和通用引用,即template <typename T> ... T&&
。 -
使用
std::move
与右值引用(像你的A&&
)。
所以f1
和f4
都是可行的解决方案。他们做不同的事情,所以你必须决定你想要哪一个。
不要使用f2
或f3
对于您的示例,它们将做同样的事情,但习惯上使用std::move
A f(A&& a) {
// use std::move(a)
}
函数模板的情况略有不同
template<typename A>
A f(A&& a) {
// use std::forward<A>(a)
}
不同之处在于第二个版本可以同时接收左值和右值(Scott Meyers将它们命名为"通用引用"),而第一个版本只能接收右值。
- 将对象移动到std::shared_ptr
- 何时在引用或唯一指针上使用移动语义
- 如何从具有移动语义的类对象中生成共享指针
- 将shared_ptr移动到<StructA>shared_ptr<变体<结构A、结构 B>>
- C / C++ 移位/偏移/向左或向右移动位图?
- MSVC将仅移动结构参数解释为指针
- 自定义先决条件对移动分配运算符有效吗
- 返回值优化:显式移动还是隐式
- 当有分配器意识的容器被复制/移动时,反弹分配器是否被复制/移走
- 为什么复制而不是移动数据元素?
- 可以使用移动语义更改或改进此C++代码吗?
- 使lambda不可复制/不可移动
- c++在使用指针时移动语义
- 将QGraphicsItem的移动区域限制在多边形区域内
- SendInput()鼠标移动计算
- 按值 C++ 返回时进行双倍移动
- 移动二维数组中的字符
- 为什么不调用移动构造函数?(默认情况下只有构造器,没有别的)
- 安全到标准:移动会员?
- OpenVR:向视图方向移动