c++ - 当在右值引用上调用 std::move 时会发生什么?

标签 c++ c++11 move move-semantics rvalue-reference

考虑以下 C++ 程序:

string construct(string&& s) {
    // Passing a r-value reference as an argument to the assignment operator
    string constructed = s;
    return constructed;
}

int main() {
    string original = "Hello";
    string temp1 = construct(std::move(original));

    printf("%s\n", original.c_str()); // Prints "Hello", so original has not changed
    return 0;
}
现在我执行的一个小变化是在 r 值引用参数上调用 std::move :
string constructWithMove(string&& s) {
    // Passing a cast to an r-value reference using r-value reference as an argument.
    string constructed = std::move(s);
    return constructed;
}

int main() {
    string original = "Hello";
    string temp = constructWithMove(std::move(original));

    printf("%s\n", original.c_str()); // Prints "", original is set to the empty string, WHY???
    return 0;
} 
所以看起来将 r 值引用转换为 r 值引用会引发一些特殊的事情。 为什么在第一种情况下原始字符串保留其值但在第二种情况下不保留 ?

最佳答案

What happens when std::move is called on a rvalue reference?

std::move将参数转换为右值引用,然后返回。

Is std::move(r_value_reference_argument) undefined


不。

// Prints "", original is set to the empty string, WHY???

What's happening here?


因为来自 std::move 的结果是一个 r 值(更具体地说是 x 值)。并被传递给 std::string 的构造函数,它调用 move 构造函数。您正在观察从中移出的字符串。
请注意,这种 move 使原始字符串处于未指定状态。不能保证它是空的,甚至与它过去包含的内容也不不同。也不保证不为空。

OK, but why in the first case the original string is not empty?


因为 s是一个 lvalue1,因此使用了复制构造函数。复制构造函数不修改原始字符串。
1 简单的经验法则:如果它是一个名称,那么它就是一个左值。

关于c++ - 当在右值引用上调用 std::move 时会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63105858/

相关文章:

c++ - Makefile 隐式规则不起作用

c++ - 在重载类方法上使用 std::bind()

c++ - 海湾合作委员会 : C++11 inline object initialization (using "this") does not work when there is a virtual inheritance in hierarchy

c++ - 如何在 C++ 中同时转换右值和左值参数?

c++ - 哪些规则确定对象是否可轻松复制

c++ - 不可复制和 move 构造函数

c++ - boost asio 和 endian

c++ - 我如何用两个不同的参数值调用我的模拟方法两次

c++ - 用于 linux 的 c 程序,用于获取设备的序列号,用于非 root 用户

c++ - 使用 Code::Blocks GNU 编译器编译多线程代码