Search code examples
c++c++11move-semanticsrvalue-referencevalue-categories

Reason to use std::move on rvalue reference parameter


I was reading a book about data structure implemented in C++, I dont understand a code snippet, it's part of vector class

void push_back(object &&x) {
        //do something
        objects[size++] = std::move(x);
    }

I know that std::move return a rvalue reference of the object, but the push_back member function already has rvalue reference x as parameter, isn't the std::move here unnecessary?

Another question is if we have a rvalue reference of a class object, we still need to use std::move on its member if we want to call move instead of copy right? like the code below:

A& operator=(A&& other) {
     member = std::move(other.member);
     return *this;
}

Solution

  • isn't the std::move here unnecessary?

    No. Types and value categories are different things.

    (emphasis mine)

    Each C++ expression (an operator with its operands, a literal, a variable name, etc.) is characterized by two independent properties: a type and a value category.

    The following expressions are lvalue expressions:

    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;

    std::move converts lvalue to rvalue (xvalue). As a named variable, x is an lvalue, std::move converts it to rvalue in objects[size++] = std::move(x); then the move assignment operator is supposed to be used. Otherwise, copy assignment operator will be used instead; lvalue can't be bound to rvalue reference.

    we still need to use std::move on its member if we want to call move instead of copy right?

    Yes, same reason as above.