Ответы:
Это безопасно. Const ref продлевает временный срок службы. Объем будет являться областью действия конт.
Время жизни временного объекта может быть увеличено путем привязки к ссылке на постоянное значение или к ссылке на значение (начиная с 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()
возвращает ссылки на локальный объект или ссылка , что оно само продление срока эксплуатации какого - то объекта, увеличение срока эксплуатации никак не загнуться.
Здесь не должно быть никаких проблем, благодаря продлению срока службы . Вновь построенный объект будет существовать до тех пор, пока ссылка не выйдет из области видимости.
Да, это совершенно безопасно: привязка к const
ссылке продлевает время существования временного объекта до объема этой ссылки.
Обратите внимание, что поведение не является транзитивным, хотя. Например, с
const auto& cc = []{
const auto& c = SomeClass{};
return c;
}();
cc
болтается.
Это безопасно.
[class.temporary]/5
: Есть три контекста, в которых временные объекты уничтожаются в другой точке, чем конец полного выражения . [..]
[class.temporary]/6
Третий контекст - это когда ссылка связана с временным объектом. Временный объект, к которому привязана ссылка, или временный объект, являющийся полным объектом подобъекта, к которому привязана ссылка, сохраняется в течение всего времени жизни ссылки, если значение glvalue, к которому привязана ссылка, было получено с помощью одного из следующих : [здесь много всего]
Это безопасно в этом конкретном случае. Однако обратите внимание, что не все временные данные безопасны для захвата по константной ссылке ... например
#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)!