I have been coding in C++ for past few years. But there is one question that I have not been able to figure out. I want to ask, are all temporaries in C++, rvalues?
If no, can anyone provide me an example where temporary produced in the code is an lvalue?
rvalues are defined by exclusion. Every expression is either an lvalue or an rvalue, so, an rvalue is an expression that does not represent an object occupying some identifiable location in memory.
In C++ temporaries are unnamed objects that compiler creates in various contexts. The typical uses include reference initialization, argument passing, evaluation of expressions (including standard type conversions), function returns, and exceptions (throw expressions).
An lvalue (3.10) of a non-function, non-array type T can be converted 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. They are declared using the '&' before the name of the variable.
No.
The C++ language specification never makes such a straightforward assertion as the one you are asking about. It doesn't say anywhere in the language standard that "all temporary objects are rvalues". Moreover, the question itself is a bit of misnomer, since the property of being an rvalue in the C++ language is not a property of an object, but rather a property of an expression (i.e. a property of its result). This is actually how it is defined in the language specification: for different kinds of expressions it says when the result is an lvalue and when it is an rvalue. Among other things, this actually means that a temporary object can be accessed as an rvalue as well as an lvalue, depending on the specific form of expression that is used to perform the access.
For example, the result of literal 2 + 3
expression is obviously an rvalue, a temporary of type int
. We cannot apply the unary &
to it since unary &
requires an lvalue as its operand
&(2 + 3); // ERROR, lvalue required
However, as we all know, a constant reference can be attached to a temporary object, as in
const int &ri = 2 + 3;
In this case the reference is attached to the temporary, extending the lifetime of the latter. Obviously, once it is done, we have access to that very same temporary as an lvalue ri
, since references are always lvalues. For example, we can easily and legally apply the unary &
to the reference and obtain a pointer to the temporary
const int *pi = &ri;
with that pointer remaining perfectly valid as long as the temporary persists.
Another obvious example of lvalue access to a temporary object is when we access a temporary object of class type through its this
pointer. The result of *this
is an lvalue (as is always the case with the result of unary *
applied to a data pointer), yet it doesn't change the fact that the actual object might easily be a temporary. For a given class type T
, expression T()
is an rvalue, as explicitly stated in the language standard, yet the temporary object accessed through *T().get_this()
expression (with the obvious implementation of T::get_this()
) is an lvalue. Unlike the previous example, this method allows you to immediately obtain a non-const-qualified lvalue, which refers to a temporary object.
So, once again, the very same temporary object might easily be "seen" as an rvalue or as an lvalue depending on what kind of expression (what kind of access path) you use to "look" at that object.
Prasoon Saurav already linked a very good clc++ thread. In there, James Kanze explains why the question doesn't really make sense. It boils down to:
For that reason, the question doesn't make sense.
A good example is the following code:
int main() { const int& ri = 4; std::cout << ri << std::endl; }
The temporary int with value 4
is not an expression. The expression ri
that's printed is not a temporary. It's an lvalue, and refers to a temporary.
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