Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rvalue reference or lvalue?

I've got a question of similiar nature like this one posted 5 years ago: Why are rvalues references variables not rvalue?

My major concern is why can I do this:

int&& k = 3;
k++;

but I cannot do this:

(static_cast<int&&>(3))++;

I've always interpreted rvalue references as lvalues since rvalue reference variables are lvalues. But apparently that is not the case. Can someone explain to me why the (static_cast<int&&>(3))++; results in using rvalue as lvalue ?

like image 254
domdrag Avatar asked Sep 27 '20 13:09

domdrag


People also ask

Is 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 is the purpose of an rvalue reference?

Rvalue references is a small technical extension to the C++ language. Rvalue references allow programmers to avoid logically unnecessary copying and to provide perfect forwarding functions. They are primarily meant to aid in the design of higer performance and more robust libraries.

Can you pass an lvalue to an rvalue reference?

By overloading a function to take a const lvalue reference or an rvalue reference, you can write code that distinguishes between non-modifiable objects (lvalues) and modifiable temporary values (rvalues). You can pass an object to a function that takes an rvalue reference unless the object is marked as const .

What is the difference between an lvalue and an rvalue?

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.

What is the difference between rvalue and lvalue?

rvalue references extend the lifespan of the temporary object to which they are assigned. Non-const rvalue references allow you to modify the rvalue. Important: lvalue references can be assigned with the rvalues but rvalue references cannot be assigned to the lvalue .

What is an R-value reference in C++?

L-value references to const objects are particularly useful because they allow us to pass any type of argument (l-value or r-value) into a function without making a copy of the argument. C++11 adds a new type of reference called an r-value reference.

Can We initialize an R-value with an L-value in Java?

R-values references cannot be initialized with l-values. R-value references have two properties that are useful. First, r-value references extend the lifespan of the object they are initialized with to the lifespan of the r-value reference (l-value references to const objects can do this too).

What is R-value in C++11?

C++11 adds a new type of reference called an r-value reference. An r-value reference is a reference that is designed to be initialized with an r-value (only). While an l-value reference is created using a single ampersand, an r-value reference is created using a double ampersand: R-values references cannot be initialized with l-values.


1 Answers

The confusion is probably arising from the difference between r-value and r-value reference. The former is a value-category which only applies to expressions, while the latter is a type which applies to variables (technically it would need to be an r-value reference of some type, e.g. r-value reference to int).

So the difference between the snippets you've shown is not actually related to the type of the variable, but the value-category of the expression. Postfix operator++ requires the value-category of the operand to be an l-value, regardless of the type of the operand.

In k++, the expression k is an l-value (roughly speaking, it has a name), which is its value-category. The type of the variable k is an r-value reference, but that's fine.

In (static_cast<int&&>(3))++, the expression static_cast<int&&>(3) is an r-value (it doesn't have a name), which is its value-category. Regardless of the type of static_cast<int&&> (which is int), the value-category is wrong, and so you get an error.

Note that the error message using rvalue as lvalue is referring to the value-category of the expression being used. It has nothing to do with the types of the variables.

like image 51
cigien Avatar answered Oct 23 '22 23:10

cigien