I have this C++ test code snippet,
#include <vector>
class A {
std::vector<int> x;
public:
A(std::vector<int>&& _x) : x(_x) {}
};
class B {
A a;
public:
B(std::vector<int>&& _x) : a(/*move(*/_x/*)*/) {}
};
I'm passing _x to B as rvalue reference, but it's getting converted to lvalue when passed into A's constructor and I have to use std::move() to make it work. My question is why _x is lvalue and not an rvalue reference in a()?
An lvalue reference can bind to an lvalue, but not to an rvalue.
An lvalue is an expression that yields an object reference, such as a variable name, an array subscript reference, a dereferenced pointer, or a function call that returns a reference. An lvalue always has a defined region of storage, so you can take its address. An rvalue is an expression that is not an lvalue.
An lvalue refers to an object that persists beyond a single expression. An rvalue is a temporary value that does not persist beyond the expression that uses it.
An lvalue reference is formed by placing an & after some type. An rvalue reference is formed by placing an && after some type. An rvalue reference behaves just like an lvalue reference except that it can bind to a temporary (an rvalue), whereas you can not bind a (non const) lvalue reference to an rvalue.
Quote from WIKI
For safety reasons, some restrictions are imposed. A named variable will never be considered to be an rvalue even if it is declared as such. To get an rvalue, the function template std::move() should be used. Rvalue references can also be modified only under certain circumstances, being intended to be used primarily with move constructors.
Anything that has a name is an lvalue reference. You have to use std::move on parameters to pass them on as rvalue references.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With