Время жизни rvalue, связанное со статической константной ссылкой

Учти это:

std::string foo();

void bar() {
         const std::string& r1 = foo();
  static const std::string& r2 = foo();
}

Я знаю, что время жизни строки, полученной в результате первого вызова foo(), будет продлено до времени жизни r1.

А как насчет временной привязки к r2? Будет ли он жить до конца области действия или останется там при повторном вводе bar()?

Примечание. Меня не интересует, делает ли это конкретный компилятор. (Меня интересует тот, который мы используем, и я могу легко протестировать его.) Я хочу знать, что стандарт говорит об этом.


person sbi    schedule 14.07.2015    source источник
comment
Независимо от ответа, это кажется плохим стилем кодирования, поэтому с хорошим стилем кодирования вопрос никогда не должен возникать.   -  person Serge Rogatch    schedule 14.07.2015
comment
@SergeRogatch Вместо этого лучше сказать, что использовать.   -  person Melebius    schedule 14.07.2015
comment
@Melebius: Это станет возможным только тогда, когда будет заявлена ​​фактическая цель.   -  person Lightness Races in Orbit    schedule 14.07.2015
comment
Это совершенно тривиально, чтобы проверить на себе...   -  person Lightness Races in Orbit    schedule 14.07.2015


Ответы (1)


Временное значение продлевается до времени существования ссылки.

[C++14: 12.2/5]: Временный объект, к которому привязана ссылка, или временный объект, являющийся полным объектом подобъекта, к которому привязана ссылка, сохраняется в течение всего времени существования ссылки, за исключением:

  • Временная привязка к элементу ссылки в конструкторе ctor-initializer (12.6.2) сохраняется до выхода из конструктора.
  • Временная привязка к ссылочному параметру в вызове функции (5.2.2) сохраняется до завершения полного выражения, содержащего вызов.
  • Время жизни временной привязки к возвращаемому значению в операторе возврата функции (6.6.3) не продлевается; временное уничтожается в конце полного выражения в операторе return.
  • Временная привязка к ссылке в new-initializer (5.3.4) сохраняется до завершения полного выражения, содержащего new-initializer. [ Пример:

    struct S { int mi; const std::pair<int,int>& mp; };
    S a { 1, {2,3} };
    S* p = new S{ 1, {2,3} }; // Creates dangling reference
    

—конец примера ] [Примечание: это может привести к появлению висячей ссылки, и реализациям рекомендуется выдавать предупреждение в таком случае. —конец примечания ]

(В частности, обратите внимание, что ни один из пунктов списка не соответствует этому сценарию.)

Так что, в данном случае, по существу, пока программа не закончится.

Мы можем, конечно, проверить это довольно тривиально:

#include <iostream>

struct Tracked
{
    Tracked() { std::cout << "ctor\n"; };
    Tracked(const Tracked&) { std::cout << "copy\n"; };
    ~Tracked() { std::cout << "dtor\n"; };
};

void foo()
{
    static const Tracked& ref = Tracked();
}

int main()
{
    std::cout << "main()\n";
    foo();
    std::cout << "bye\n";
}

Результат:

main()
ctor
пока
dtor

(демонстрация)

person Lightness Races in Orbit    schedule 14.07.2015