为什么在C ++ 11中有&时使用std :: move?
可能重复:
有人可以解释移动语义给我吗?
我最近参加了一个C ++ 11研讨会,并给出了以下的build议。
when you have && and you are unsure, you will almost always use std::move
任何人可以向我解释为什么你应该使用std::move
,而不是一些替代品和一些情况下,当你不应该使用std::move
?
首先,我将解决的问题可能存在一个误解:
每当你在代码中看到T&& t
(而T是一个实际的types,而不是一个模板types),请记住t
的值是一个左值(引用),而不是右值(临时)。 这很混乱。 T&&
仅仅意味着t
是由一个值为1的对象构成的,但t
本身是一个左值,而不是右值。 如果它有一个名字(在这种情况下, t
),那么它是一个左值,不会自动移动,但如果它没有名称( 3+4
的结果),那么它是一个右值,并会自动移动到它的结果它可以。 types (在这种情况下T&&
)几乎与variables的值类别无关(在本例中为左值)。
这就是说,如果你有写在你的代码,这意味着你有一个variables是一个临时的参考,可以销毁,如果你想。 如果你需要多次访问variables,你不想std::move
从它std::move
,否则会失去它的价值。 但是最后一次,如果你愿意的话, std::move
它的值移到另一个T
是安全的。 (95%的时间,这就是你想要做的)
1.如果T
是模板types,则T&&
是一个转发引用,在这种情况下,您最后一次使用std::forward<T>(t)
而不是std::move(t)
。 看到这个问题
我发现这篇文章对于一般的右值引用很有启发。 他提到std::move
走向最后。 这可能是最相关的报价:
我们需要从
<utility>
使用std::move
–std::move
是一种说法,“好吧,对上帝诚实我知道我有一个左值,但我希望它是一个右值”。std::move
本身不会移动任何东西; 它只是将左值变成右值,以便您可以调用移动构造函数。
假设你有一个如下所示的移动构造函数:
MyClass::MyClass(MyClass&& other): myMember(other.myMember) { // Whatever else. }
当您使用语句other.myMember
,返回的值是一个左值。 因此,代码使用复制构造函数来初始化this->myMember
。 但是由于这是一个移动构造函数,我们知道other
是一个临时对象,因此它的成员也是。 所以我们真的想用更高效的移动构造函数来初始化this->myMember
。 使用std::move
可以确保编译器将其他other.myMember
视为右值引用,并根据需要调用移动构造函数:
MyClass::MyClass(MyClass&& other): myMember(std::move(other.myMember)) { // Whatever else. }
只是不要使用std::move
你需要保留的对象 – 移动构造函数几乎可以保证传递给它们的任何对象。 这就是为什么他们只用于临时使用。
希望有所帮助!
当你有一个T&&
types的对象,一个右值,这意味着这个对象是安全的被移动,因为没有人会在以后依赖它的内部状态。
移动不应该比复制贵,你几乎总是想要移动它。 而要移动它,你必须使用std::move
函数。
什么时候应该避免std::move
,即使它是安全的? 我不会在一些简单的例子中使用它,例如:
int x = 0; int y = std::move(x);
除此之外,我看不出什么缺点。 如果它不使代码复杂化,应尽可能移动恕我直言。
另一个例子,你不想移动的地方是返回值。 该语言保证返回值(至less)被移动,所以你不应该写
return std::move(x); // not recommended
(如果幸运的话, 返回值优化命中,这比移动操作更好。)
当您需要将某个对象的内容“转移”到别处时,您可以使用移动,而无需进行复制。 也可以使用std :: move来获取临时对象的内容而不用拷贝。
检出这个链接