Once the compiler has decided to call a particular member function (int &std::vector<int>::front()
, say) the type system only knows that an int &
is returned, so it has to treat that as an lvalue even though its lifetime is limited to that of the owner temporary.
Before C++11 it was not possible for a member function to be overloaded according to the value category of the object it is being called on (see What is "rvalue reference for *this"?), only on cv-qualification of the object; and a non-const temporary is clearly not const
so the non-const
overloads must be available.
As well as the potentially dangling lvalue references you've identified, this led in C++03 to the situation where operator<<
on a temporary ostream
could be called with a char
(member function operator) but not with a string
(free operator); C++11 fixes this with free operator overloads for rvalue references and rvalue *this
overload for member functions.
Rvalue *this
allows three overloads for front
:
T &front() & { return data_[0]; }
const T &front() const & { return data_[0]; }
T &&front() && { return std::move(data_[0]); }
The different function body for the rvalue overload is a bit of a wart; this is because the ref-qualifier has no effect on member of *this
access within the body of a member function.