A temporary is an unnamed object (the results of some
expressions), and is always an rvalue. Or perhaps one should
better say that an expression which results in an rvalue is
a temporary.
In C, rvalues/temporaries weren't really objects (in the sense
the standard uses the word "object": something that is located
in memory). Thus, for example, they weren't cv-qualified
(an expression like 3 + 5
has type int
, and not int const
,
and cv-qualifiers are ignored on function return values) and you
can't take their address (because they aren't in memory, they
don't have an address). In C++, the issue is clouded by class
types: you can call a member function on an rvalue, and that
member function will have a this
pointer, which means that
even rvalues (of class type) must have an address in memory, and
that cv-qualifications have meaning, since if the return type is
const
, you can't call a non-const function on it.
In the end, although the concepts of rvalue and temporary are
very closely related, the C++ standard uses the words in
slightly different ways. The results of an expression are
either an rvalue or an lvalue (C++11 adds other possibilities,
but you can ignore them until you're an expert), and this
distinction concerns all types. When the C++ standard speaks of
a temporary, it is an rvalue which is (or has become) an object.
For the most part, these have class type; there are very few
cases where you would have a temporary which is not of class
type in well written code, except where templates are
involved. The distinction is important, because even if the
built-in &
operator is illegal on an rvalue, rvalues of class
type have a defined "lifetime" and a memory address. That
lifetime is until the end of the full expression. So when class
types are concerned, the difference between a temporary and
a named value is mainly that the temporary doesn't have a name,
and it has a different lifetime. The lifetime of a class type
is important for two reasons: first, it determines when the
destructor is called, and second, if the object "leaks"
a pointer to internal data, e.g. like std::string::c_str()
, it
determines how long this pointer may be valid.
Finally, I mention templates because that is about the only time
you would have a const reference to a non-class type. The usual
convention for in arguments is pass by value for non-class
types, and by const reference for class types; the author of the
template, however, doesn't know whether T
will be a class
types or not, and in most cases, will define his function to
take a T const&
. This will be, in practice, about the only
time you'll end up with a temporary object of non-class type
(and if the template saves the address of the argument, you may
have problems).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…