Search code examples
c++rvalue-reference

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 ?


Solution

  • 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.