为什么在 C++11 中有 && 时使用 std::move ?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14486367/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why do you use std::move when you have && in C++11?
提问by pyCthon
Possible Duplicate:
What is move semantics?
可能的重复:
什么是移动语义?
I recently attended a C++11 seminar and the following tidbit of advice was given.
我最近参加了一个 C++11 研讨会,并给出了以下建议。
when you have && and you are unsure, you will almost always use std::move
Could any one explain to me why you should use std::move
as opposed to some alternatives and some cases when you should not use std::move
?
任何人都可以向我解释为什么你应该使用std::move
而不是一些替代品和一些你不应该使用的情况std::move
?
回答by Mooing Duck
First, there's probably a misconception in the question I'll address:
Whenever you see T&& t
in code (And T is an actual type, not a template type), keep in mind the value category of t
is an lvalue(reference), not an rvalue(temporary) anymore. It's very confusing. The T&&
merely means that t
is constructedfrom an object that was an rvalue 1, but t
itselfis an lvalue, not an rvalue. If it has a name (in this case, t
) then it's an lvalue and won't automatically move, but if it has no name (the result of 3+4
) then it is an rvalue and will automaticallymove into it's result if it can. The type(in this case T&&
) has almost nothing to do with the value category of the variable (in this case, an lvalue).
首先,在我要解决的问题中可能存在误解:
每当您T&& t
在代码中看到(并且 T 是实际类型,而不是模板类型)时,请记住的值类别t
是左值(引用),而不是右值(暂时)了。这很令人困惑。的T&&
,仅仅装置t
被构造从一个对象,它是一个rvalue 1,但t
本身是一个左值,而不是一个右值。如果它有一个名字(在这种情况下,t
),那么它是一个左值,不会自动移动,但如果它没有名字(结果3+4
),那么它是一个右值,如果可以的话,它会自动移动到它的结果中。的类型(在这种情况T&&
) 几乎与变量的值类别无关(在本例中为左值)。
That being said, if you have T&& t
written in your code, that means you have a reference to a variable that wasa temporary, and it is ok to destroy if you want to. If you need to access the variable multiple times, you do notwant to std::move
from it, or else it would lose it's value. But the last time you acccess t
it is safe to std::move
it's value to another T
if you wish. (And 95% of the time, that's what you want to do). All of this also applies to auto&&
variables.
话虽这么说,如果你T&& t
写在你的代码,这意味着你有一个变量的引用是一个暂时的,它是确定摧毁,如果你想。如果您需要访问的变量多次,你不希望std::move
从它,否则就会失去它的价值。但是,如果您愿意,您最后一次访问t
它对std::move
另一个人的价值是安全的T
。(并且 95% 的时间,这就是您想要做的)。所有这些也适用于 auto&&
变量。
1. if T
is a template type, T&&
is a forwarding reference instead, in which case you use std::forward<T>(t)
instead of std::move(t)
the last time. See this question.
1.ifT
是模板类型,T&&
是转发引用代替,在这种情况下你用的std::forward<T>(t)
不是std::move(t)
最后一次。看到这个问题。
回答by Xavier Holt
I found this articleto be pretty enlightening on the subject of rvalue references in general. He mentions std::move
towards the end. This is probably the most relevant quote:
我发现这篇文章对一般的右值引用主题非常有启发性。他std::move
在最后提到。这可能是最相关的引用:
We need to use
std::move
, from<utility>
--std::move
is a way of saying, "ok, honest to God I know I have an lvalue, but I want it to be an rvalue."std::move
does not, in and of itself, move anything; it just turns an lvalue into an rvalue, so that you can invoke the move constructor.
我们需要使用
std::move
, from<utility>
--std::move
是一种说法,“好吧,老实说,我知道我有一个左值,但我希望它是一个右值。”std::move
本身不会移动任何东西;它只是将左值转换为右值,以便您可以调用移动构造函数。
Say you have a move constructor that looks like this:
假设您有一个如下所示的移动构造函数:
MyClass::MyClass(MyClass&& other): myMember(other.myMember)
{
// Whatever else.
}
When you use the statement other.myMember
, the value that's returned is an lvalue. Thus the code uses the copyconstructor to initialize this->myMember
. But since this is a move constructor, we know that other
is a temporary object, and therefore so are its members. So we really want to use the more-efficient moveconstructor to initialize this->myMember
. Using std::move
makes sure that the compiler treats other.myMember
like an rvalue reference and calls the move constructor, as you'd want it to:
当您使用 statement 时other.myMember
,返回的值是一个左值。因此,代码使用复制构造函数来初始化this->myMember
. 但由于这是一个移动构造函数,我们知道它other
是一个临时对象,因此它的成员也是如此。所以我们真的想使用更高效的移动构造函数来初始化this->myMember
. Usingstd::move
确保编译器other.myMember
像右值引用一样对待并调用移动构造函数,正如您希望的那样:
MyClass::MyClass(MyClass&& other): myMember(std::move(other.myMember))
{
// Whatever else.
}
Just don't use std::move
on objects you need to keep around - move constructors are pretty much guaranteed to muck up any objects passed into them. That's why they're only used with temporaries.
只是不要std::move
在您需要保留的对象上使用- 移动构造函数几乎可以保证处理传递给它们的任何对象。这就是为什么它们只与临时对象一起使用。
Hope that helps!
希望有帮助!
回答by Philipp Cla?en
When you have an object of type T&&
, a rvalue, it means that this object is safe to be moved, as no one else will depend on its internal state later.
当你有一个类型T&&
为右值的对象时,这意味着这个对象可以安全地移动,因为以后没有其他人会依赖于它的内部状态。
As moving should never be more expensive than copying, you will almost always want to move it. And to move it, you have to use the std::move
function.
由于搬家永远不会比复制更昂贵,因此您几乎总是想搬家。要移动它,您必须使用该std::move
功能。
When should you avoid std::move
, even if it would be safe? I wouldn't use it in trivial examples, e.g.,:
什么时候应该避免std::move
,即使它是安全的?我不会在琐碎的例子中使用它,例如:
int x = 0;
int y = std::move(x);
Beside that, I see no downsides. If it does not complicate the code, moving should be done whenever possible IMHO.
除此之外,我看不出有什么缺点。如果它不会使代码复杂化,恕我直言,应尽可能进行移动。
Another example, where you don't want to move are return values. The language guarantees that return values are (at least) moved, so you should not write
另一个示例,您不想移动的地方是返回值。该语言保证返回值(至少)被移动,所以你不应该写
return std::move(x); // not recommended
(If you are lucky, return value optimizationhits, which is even better than a move operation.)
(如果幸运的话,返回值优化命中,这甚至比移动操作更好。)
回答by Rahul Tripathi
You can use move when you need to "transfer" the content of an object somewhere else, without doing a copy. It's also possible for an object to take the content of a temporary object without doing a copy, with std::move.
当您需要将对象的内容“转移”到其他地方而不进行复制时,您可以使用 move。对象也可以使用 std::move 获取临时对象的内容而不进行复制。