为什么在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::movestd::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来获取临时对象的内容而不用拷贝。

检出这个链接