Why to use std::move despite the parameter is an r-value reference

拟墨画扇 提交于 2021-02-07 06:22:22

问题


I am confused about using std::move() in below code:

If I uncomment line at (2) the output would be: 1 2 3 but if I uncomment line at (1) output would be nothing which means that move constructor of std::vector was called!

Why do we have to make another call to std::move at (1) to make move constructor of std::vector to be called?

What I understood that std::move get the r-value of its parameter so, why we have to get the r-value of r-value at (1)?

I think this line _v = rv; at (2) is more logical and should make std::vector move constructor to be called without std::movebecause rv itself is r-value reference in the first place.

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;
}

回答1:


Every named object is Lvalue ref about Lvalue:

the name of a variable, a function, a template parameter object (since C++20), or a data member, regardless of type, such as std::cin or std::endl. Even if the variable's type is rvalue reference, the expression consisting of its name is an lvalue expression;

vector has two overloads of assignment operator, one for Lvalue reference and another for Rvalue reference.

vector::operator=(const vector&) // copy assignment operator
vector::operator=(vector&&) // move assignment operator

Overload which takes Lvalue reference is called when Lvalue is passed as argument for operator=. Details here

when a function has both rvalue reference and lvalue reference overloads, the rvalue reference overload binds to rvalues (including both prvalues and xvalues), while the lvalue reference overload binds to lvalues

By std::move(rv); you cast rv - Lvalue to Rvalue reference, and operator= which takes Rvalue reference is called. Otherwise, Lvalue binds to Lvalue reference and vector is copied instead of being moved.



来源:https://stackoverflow.com/questions/54951635/why-to-use-stdmove-despite-the-parameter-is-an-r-value-reference

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!