【发布时间】:2020-05-25 14:01:00
【问题描述】:
如果我在当前范围内的堆栈对象上使用 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;
}
结果:
vec[0]: stackoverflow
str:
如果我将 std::move 用于右值或 const 左值函数参数,则会复制内容。
#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;
}
结果:
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
为什么 std::move 的行为不同?
【问题讨论】:
-
请记住,
std::move实际上并没有移动任何东西。它只是一个 cast 到右值引用。该右值引用随后是否被移动或复制取决于上下文以及对象是否实现移动操作以及源对象是否为const。 -
在第一个例子中,
actually moving the ownership of the data是 std::string 的移动构造函数。在第二个示例中,您只是发送一个右值 ref。您可以在此处手动获取传递的 std::vector 的所有权。
标签: c++ move-semantics