尽管参数是 r 值引用,但为什么要使用 std::move

Isl*_*een 12 c++ move c++11 c++14 stdmove

我对std::move()在下面的代码中使用感到困惑:

如果我在 (2) 处取消注释行,输出将是:1 2 3但如果我在 (1) 处取消注释行,输出将什么都不是,这意味着std::vector调用了移动构造函数!

为什么我们必须再次调用std::moveat (1) 来调用移动构造函数std::vector

我的理解是std::move得到r-value其参数的话,为什么我们要得到r-valuer-value在(1)?

我认为_v = rv;(2) 中的这一行更合乎逻辑,应该使std::vector移动构造函数不被调用,std::move因为rv它首先是r-value引用。

template <class T>
class A
{
public:
    void set(std::vector<T> & lv)
    {

    }  
    void set(std::vector<T> && rv)
    {           
        //_v = std::move(rv);          (1)
        //_v = rv;                     (2)
    }

private:
    std::vector<T> _v;
};

int main()
{
    std::vector<int> vec{1,2,3};
    A<int> a;

    a.set(std::move(vec));
    for(auto &item : vec)
        cout << item << " ";
    cout << endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

raf*_*x07 11

每个命名对象都是关于 Lvalue 的Lvalue引用

变量、函数、模板参数对象(C++20 起)或数据成员的名称,无论类型如何,例如 std::cin 或 std::endl。即使变量的类型是右值引用, 由其名称组成表达式也是左值表达式

vector 有两个赋值运算符的重载,一个用于左值引用,另一个用于右值引用。

vector::operator=(const vector&) // copy assignment operator
vector::operator=(vector&&) // move assignment operator
Run Code Online (Sandbox Code Playgroud)

当 Lvalue 作为 的参数传递时,会调用采用 Lvalue 引用的重载operator=详情在这里

当函数同时具有右值引用和左值引用重载时,右值引用重载绑定到右值(包括纯右值和 xvalues),而左值引用重载绑定到左值

通过std::move(rv);您将rv- Lvalue 转换为 Rvalue 引用,并且operator=调用了 Rvalue 引用。否则,左值绑定到左值引用,向量被复制而不是被移动。