Упомянутая вами цитата предназначена специально для возврата ссылки из функции и привязки этой ссылки к временной:
const T& f() { return T(); };
В вашем коде это не так, потому что вы привязываете временную ссылку к ссылке на стороне вызова, а не в операторе возврата. В своих комментариях вы упоминаете, что при изменении кода на:
T f() { return T(); }
T&& r = f();
время жизни по-прежнему продлевается, но это неправильно. Временные жизни на время действия оператора return
, в течение которого он копируется в возвращаемое значение. После завершения копирования время жизни временного заканчивается. На вызывающей стороне у вас есть другое временное (результат f()
), время жизни которого увеличивается.
Но нет никаких сомнений в том, что срок службы временных конструкций продлевается. Если вы определите деструктор для класса A с любым сообщением, оно будет напечатано в конце main() или есть?
Это утверждение также неверно. Вы видите результаты оптимизации возвращаемого значения (RVO). Вместо создания временного объекта для T()
внутри функции и другого для возвращаемого значения компилятор создает два объекта в одном и том же месте. Вы, вероятно, видите один объект в выводе программы, но теоретически их два.
Вы можете попробовать использовать g++ с -fno-elide-constructors, и вы сможете увидеть оба временных объекта, один из которых расширен, а другой не будет.
Кроме того, вы можете вернуть ссылку:
const A& f() { return A(); }
const A& r = f();
Что должно показать, как временное умирает до того, как r
выйдет из области видимости.
По сути, это тот же тест, ингибирующий
$ g++ --версия | голова -1
g++ (ССЗ) 4.3.2
$ кошка x.cpp
#include <iostream>
struct X {
X() { std::cout << "X\n"; }
~X() { std::cout << "~X\n"; }
};
X f() { return X(); }
int main() {
const X& x = f();
std::cout << "still in main()\n";
}
$ g++ -o t1 x.cpp && ./t1
X
still in main()
~X
$ g++ -fno-elide-constructors -o t2 x.cpp && ./t2
X
~X
still in main()
~X
$ clang++ -версия | голова -1
$ clang версии 3.2 (теги/RELEASE_32/final)
$ clang++ -fno-elide-constructors -o t3 x.cpp && ./t3
X
~X
still in main()
~X
$ кошка y.cpp
#include <iostream>
struct X {
X() { std::cout << "X\n"; }
~X() { std::cout << "~X\n"; }
};
const X& f() { return X(); }
int main() {
const X& x = f();
std::cout << "still in main()\n";
}
$ g++ -fno-elide-constructors -o t4 y.cpp && ./t4
X
~X
still in main()
person
David Rodríguez - dribeas
schedule
27.06.2013
return <temporary>;
, а не к присвоению возвращаемого значения функции ссылке. - person David Brown   schedule 28.06.2013f()
была определена какA f() { return A(); }
- person Belloc   schedule 28.06.2013std::cout << a1.i << '\n';
в конце main(), он все равно выведет правильный результат. - person Belloc   schedule 28.06.2013f()
, будет продлено, поскольку оно назначено ссылке. Исключение, которое вы цитируете, применяется только к функциям, которые возвращают ссылки. - person David Brown   schedule 28.06.2013