Существует специальное правило, которое позволяет возвращать временное значение в качестве значения r, а именно следующее эквивалентно - явная версия "Мне больше не нужно":
T foo()
{
T t(a, b, ...); // constructed somehow
/* ... */
return std::move(t);
}
int main()
{
T t = foo(); // we can move-construct this
}
... и неявная версия:
T foo()
{
T t(a, b, ...);
/* ... */
return t; // implicitly allow moving
}
Все это происходит после оптимизации возвращаемого значения. Это означает, что возврат по значению на самом деле довольно эффективен во многих ситуациях.