c++ - 为什么std::move复制右值或const左值函数参数的内容?

标签 c++ move-semantics

如果我在当前范围内的堆栈对象上使用 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的行为不同?

最佳答案

您的载体实际上是被复制的,而不是被移动的。这样做的原因是,尽管vec_声明为右值引用,但它表示函数体内的左值表达式。因此,将调用std::vector的副本构造函数,而不是move构造函数。原因是vec_现在是一个命名值,并且rvalues不能具有名称,因此它会折叠为lvalue。由于以下原因,以下代码将无法编译:

void foo(int&& i)
{
    int&& x = i;
}

为了解决此问题,您必须通过调用vec_再次使std::move(vec_)无名。

关于c++ - 为什么std::move复制右值或const左值函数参数的内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60147226/

相关文章:

c++ - 尝试编写可以从 std::string move 语义的字符串类

c++ - 使用 x86/x64 流 SIMD 扩展的 block 匹配优化

c++ - 为什么没有默认的 move 分配/move 构造函数?

rust - 为什么entry需要key的所有权?

c++ - 在 std::pair 支撑初始化中复制 vs move

c++ - 在仅 move 类型上强制复制(然后销毁)

c++ - 在 Windows 上工作,但在 Ubuntu 上出现段错误

c++ - 函数重载匹配模板template

c++ - _ftime/Windows 内部时间如何工作?

c++ - 查找指向对象的静态指针?