I do not understand why the following code compiles on GCC 8.0:
decltype(auto) foo(int&& r) {
return r;
}
In foo
, the declaration type of r
is int&&
, and so the return type of foo
is also int&&
. But r
itself is an lvalue, and an lvalue cannot bind to an rvalue reference.
Am I missing something?
An lvalue reference can bind to an lvalue, but not to an rvalue.
“l-value” refers to a memory location that identifies an object. “r-value” refers to the data value that is stored at some address in memory. References in C++ are nothing but the alternative to the already existing variable.
Lvalues and rvalues are fundamental to C++ expressions. Put simply, an lvalue is an object reference and an rvalue is a value. The difference between lvalues and rvalues plays a role in the writing and understanding of expressions.
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.
According to [dcl.spec.auto]/5, the return type is deduced as if the return
statement's operand was the operand of decltype
. And [dcl.type.simple]/(4.2) clearly states that, as the operand is not parenthesized, the type of the entity is the type yielded by decltype
, that is, int&&
. And indeed, r
is an lvalue ([expr.prim.id.unqual]).
Fortunately, this has been discovered and filed as bug 64892 two years ago. (I wonder why no one could find the time to fix this?)
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