Відповіді:
Це безпечно. Const ref продовжує термін експлуатації тимчасових. Областю застосування буде сфера const ref.
Термін експлуатації тимчасового об'єкта може бути продовжений шляхом прив'язки до посилання const lvalue або до посилання rvalue (оскільки C ++ 11), див. Ініціалізацію посилань .
Щоразу, коли посилання прив'язується до тимчасового або до його суб'єкта, термін дії тимчасового подовжується, щоб відповідати терміну експлуатації посилання, за такими винятками :
- тимчасове прив’язане до повернення значення функції у зворотному операторі не розширюється: воно руйнується негайно в кінці виразу повернення. Така функція завжди повертає звисаючу посилання.
- тимчасове прив’язання до посилального члена у списку ініціалізатора конструктора зберігається лише до тих пір, поки конструктор не вийде, не доки об'єкт існує. (зауважте: така ініціалізація неправильно сформована як в DR 1696).
- тимчасовий прив'язок до опорного параметра у виклику функції існує до кінця повного виразу, що містить цей виклик функції: якщо функція повертає посилання, яке переживає повний вираз, воно стає звисаючим посиланням.
- тимчасова прив'язка до посилання в ініціалізаторі, що використовується в новому виразі, існує до кінця повного виразу, що містить цей новий вираз, не так довго, як ініціалізований об'єкт. Якщо ініціалізований об'єкт переживає повний вираз, його референтний член стає звисаючим посиланням.
- тимчасове прив’язання до посилання в еталонному елементі сукупності, ініціалізованого за допомогою синтаксису прямої ініціалізації (дужки) на відміну від синтаксису (дужки) списку-ініціалізації існує до кінця повного виразу, що містить ініціалізатор.
struct A { int&& r; }; A a1{7}; // OK, lifetime is extended A a2(7); // well-formed, but dangling referenceЗагалом, термін служби тимчасового не може бути продовжений шляхом "передачі його": друга посилання, ініціалізована з посилання, до якого тимчасовий прив'язується, не впливає на її тривалість життя.
як зазначав @Konrad Rudolph (і див. останній абзац вище):
"Якщо
c.GetSomeVariable()повертає посилання на локальний об'єкт або посилання на те, що він сам подовжує термін дії якогось об'єкта, продовження терміну дії не починається"
c.GetSomeVariable()повертає посилання на локальний об'єкт або посилання , що воно саме продовження терміну експлуатації якого - то об'єкта, збільшення терміну експлуатації ніяк НЕ загнутися.
Тут не повинно виникнути жодних проблем, завдяки продовженню терміну експлуатації . Щойно збудований об’єкт протримається до тих пір, поки посилання не вийде за межі.
Це безпечно.
[class.temporary]/5: Існує три контексти, в яких темпорації руйнуються в іншій точці, ніж в кінці повного виразу . [..]
[class.temporary]/6: Третій контекст - це посилання на тимчасовий об'єкт. Тимчасовий об'єкт, до якого пов'язується посилання, або тимчасовий об'єкт, який є повним об'єктом суб'єкта, до якого посилається прив'язка, зберігається протягом життя посилання, якщо glvalue, до якого прив'язується посилання, отримано за допомогою одного з наступних : [тут багато речей]
У цьому конкретному випадку це безпечно. Однак зауважте, що не всі часові сховища безпечні для зйомки за допомогою посилання const ... наприклад
#include <stdio.h>
struct Foo {
int member;
Foo() : member(0) {
printf("Constructor\n");
}
~Foo() {
printf("Destructor\n");
}
const Foo& method() const {
return *this;
}
};
int main() {
{
const Foo& x = Foo{}; // safe
printf("here!\n");
}
{
const int& y = Foo{}.member; // safe too (special rule for this)
printf("here (2)!\n");
}
{
const Foo& z = Foo{}.method(); // NOT safe
printf("here (3)!\n");
}
return 0;
}
Посилання, отримане для z, НЕ БЕЗПЕЧНЕ для використання, оскільки тимчасовий екземпляр буде знищений в кінці повного виразу, перш ніж дійти до printfзаяви. Вихід:
Constructor
here!
Destructor
Constructor
here (2)!
Destructor
Constructor
Destructor
here (3)!