为什么来自右值引用类型的赋值不调用移动赋值运算符?

Why does an assignment from an rvalue reference type not invoke the move assignment operator?

考虑以下代码:

#include <iostream>
#include <string>

struct my_struct {
    void func(std::string&& str) {
        str_ = str;
    }

    std::string str_;
};

int main() {
    my_struct s;
    std::string str("Hello");

    s.func(std::move(str));

    std::cout << str << std::endl;
    std::cout << s.str_ << std::endl;    
}

为什么我在my_struct::func中需要一个额外的std::move来调用std::string的移动赋值运算符?额外的 std::move 究竟有什么作用?我以为它只会将给定类型转换为它的右值引用对象?

当您执行 str_ = str; 时,str 是一个命名变量。这意味着在你的函数中 str 是一个左值,而不是右值。这意味着使用复制赋值而不是移动赋值。

你需要做的是让 str 回到右值,你可以用 std::move 来做到这一点,比如

str_ = std::move(str);
void func(std::string&& str) {
    str_ = str;
}

应该是

void func(std::string&& str) {
    str_ = std::move(str);
}

因为str有名字,所以有左值。