[英]Why does std::move copy contents for a rvalue or const lvalue function argument?
If I use std::move on a stack object in the current scope, the contents are moved to destination leaving the source empty.如果我在当前范围内的堆栈对象上使用std::move ,则内容将移动到目标,而源为空。
#include <iostream>
#include <string>
#include <utility>
#include <vector>
int main()
{
std::string str("stackoverflow");
std::vector<std::string> vec;
vec.emplace_back(std::move(str));
std::cout << "vec[0]: " << vec[0] << std::endl;
std::cout << "str: " << str << std::endl;
}
Result:结果:
vec[0]: stackoverflow
str:
If I use the std::move for a rvalue or const lvalue function arguments, the contents are copied.如果我将std::move用于 rvalue 或 const lvalue 函数参数,则复制内容。
#include <iostream>
#include <memory>
#include <vector>
#include <utility>
void process_copy(std::vector<int> const & vec_)
{
std::vector<int> vec(vec_);
vec.push_back(22);
std::cout << "In process_copy (const &): " << std::endl;
for(int & i : vec)
std::cout << i << ' ';
std::cout << std::endl;
}
void process_copy(std::vector<int> && vec_)
{
std::vector<int> vec(vec_);
vec.push_back(99);
std::cout << "In process_copy (&&): " << std::endl;
for(int & i : vec)
std::cout << i << ' ';
std::cout << std::endl;
}
int main()
{
std::vector<int> v = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
process_copy(std::move(v));
std::cout << "In main: " << std::endl;
for(int & i : v)
std::cout << i << ' ';
std::cout << std::endl;
std::cout << "size: " << v.size() << std::endl;
}
Result:结果:
In process_copy (&&):
0 1 2 3 4 5 6 7 8 9 99
In main:
0 1 2 3 4 5 6 7 8 9
size: 10
Why is the behavior of std::move different?为什么 std::move 的行为不同?
You need to use std::move
if the value is bound to a variable even it is declared as rvalue revefernce ( &&
).如果值绑定到变量,即使它被声明为右值引用( &&
),您也需要使用std::move
。 ie it should be:即它应该是:
void process_copy(std::vector<int> && vec_)
{
std::vector<int> vec(std::move(vec_));
...
}
Your vector is actually copied, not moved.您的矢量实际上是复制的,而不是移动的。 The reason for this is, although declared as an rvalue reference, vec_
denotes an lvalue expression inside the function body.其原因是,尽管声明为右值引用,但vec_
表示函数体内的左值表达式。 Thus the copy constructor of std::vector
is invoked, and not the move constructor.因此调用std::vector
的复制构造函数,而不是移动构造函数。 The reason for this is, that vec_
is now a named value, and rvalues cannot have names, so it collapses to an lvalue.这样做的原因是, vec_
现在是一个命名值,而右值不能有名称,因此它会折叠为左值。 The following code will fail to compile because of this reason:由于这个原因,以下代码将无法编译:
void foo(int&& i)
{
int&& x = i;
}
In order to fix this issue, you have to make vec_
nameless again, by calling std::move(vec_)
.为了解决这个问题,你必须通过调用std::move(vec_)
再次使vec_
无名。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.