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.
k
isint &&
, but the type of the expressionk
is justint
(and that expression is an lvalue). This also means that the type ofstatic_cast<int&&>(3)
isint
rather thanint &&
. – Resile