std :: move是否可以与左值引用一起使用? std :: move如何在标准容器上工作?
#include <vector>
struct A { int a[100]; };
void foo (const A& a) {
std::vector<A> vA;
vA.push_back(std::move(a)); // how does move really happen?
}
int main () {
A a;
foo(a);
}
上面的代码编译良好.现在到处都有记载,move
避免了复制.
以下是我的查询:
The above code compiles fine. Now everywhere it's written that move
avoids copying.
Following are my queries:
-
move
在处理左值时是否真的起作用? [non]-const
参考? - 即使使用右值引用",当对象出现时如何避免复制 插入上面的标准容器中?
- Does the
move
really work when one deals with a lvalue [non]-const
reference? - Even with "rvalue reference", how is the copy avoided when the object is inserted into a standard container like above?
例如
void foo (A&& a) { // suppose we invoke this version
std::vector<A> vA;
vA.push_back(std::move(a)); // how copy is avoided?
}
std::move
不执行任何操作.它实际上将左值引用转换为右值引用.在这种情况下,移动的结果是const A &&
(顺便说一句,这完全没用).
std::move
doesn't do a move. It actually casts the lvalue reference to an rvalue reference. In this case, the result of the move is a const A &&
(which is totally useless by the way).
std::vector
对于const A &
和A &&
具有重载,因此将选择const A &
的重载,并且const A &&
隐式转换为const A &
std::vector
has an overload for a const A &
and a A &&
, so the overload with const A &
will get chosen and the const A &&
is implicitly casted to const A &
可以在const对象上调用std::move
的事实对于大多数程序员来说都是奇怪的/意想不到的行为,尽管它在某种程度上是允许的. (很可能他们有一个用例,或者没有一个用例可以阻止它)
The fact that std::move
can be called on const objects, is strange/unexpected behavior for most programmers, though it somehow is allowed. (Most likely they had a use case of it, or none to prevent it)
更具体地针对您的示例,将调用类A的move构造函数.由于A是POD,因此很可能只需要进行复制,因为所有位都只需要移动/复制到A的新实例.
More specific for your example, the move constructor of the class A will get called. As A is a POD, this most likely will just do a copy as all bits just have to move/copied to the new instance of A.
由于标准仅指定原始对象必须处于有效(尽管未指定)状态,因此您的编译器可以将位保留在A中,而不必将它们全部重置为0.实际上,大多数编译器将保留这些位就位,因为更改它们需要额外的指令,这对性能不利.
As the standard only specifies that the original object has to be in a valid though unspecified state, your compiler can keep the bits in A in place and doesn't have to reset them all to 0. Actually, most compilers will keep these bits in place, as changing them requires extra instructions, which is bad for performance.