c++ - Можно ли вернуть значение аргумента по умолчанию с помощью константной ссылки?




language-lawyer object-lifetime (2)

Можно ли вернуть значение аргумента по умолчанию с помощью константной ссылки, как в следующих примерах:

https://coliru.stacked-crooked.com/a/ff76e060a007723b

#include <string>

const std::string& foo(const std::string& s = std::string(""))
{
    return s;
}

int main()
{
    const std::string& s1 = foo();
    std::string s2 = foo();

    const std::string& s3 = foo("s");
    std::string s4 = foo("s");
}

В вашем коде и s1 и s3 являются висячими ссылками. s2 и s4 в порядке.

При первом вызове временный пустой объект std::string созданный из аргумента по умолчанию, будет создан в контексте выражения, содержащего вызов. Следовательно, он умрет в конце определения s1 , в результате чего s1 повиснет.

Во втором вызове временный объект std::string используется для инициализации s2 , затем он умирает.

В третьем вызове строковый литерал "s" используется для создания временного объекта std::string который также умирает в конце определения s3 , оставляя s3 висящим.

В четвертом вызове временный объект std::string со значением "s" используется для инициализации s4 а затем он умирает.

См. C ++ 17 [class.teven] /6.1

Временный объект, связанный с опорным параметром в вызове функции (8.2.2), сохраняется до завершения полного выражения, содержащего вызов.


Это не безопасно :

В общем, время жизни временного объекта не может быть дополнительно продлено путем «передачи его»: вторая ссылка, инициализированная из ссылки, к которой привязан временный объект, не влияет на его время жизни.





reference-binding