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