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