Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't bind lvalue to rvalue reference

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()?

like image 766
Samik Avatar asked Oct 31 '16 20:10

Samik


People also ask

Can lvalue bind to rvalue reference?

An lvalue reference can bind to an lvalue, but not to an rvalue.

Is an rvalue reference an lvalue?

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.

What are Lvalues and Rvalues?

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.

How do I create an rvalue reference?

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.


2 Answers

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.

like image 124
O_Z Avatar answered Oct 26 '22 22:10

O_Z


Anything that has a name is an lvalue reference. You have to use std::move on parameters to pass them on as rvalue references.

like image 21
Edward Strange Avatar answered Oct 26 '22 20:10

Edward Strange