Можно ли вернуть значение аргумента по умолчанию с помощью константной ссылки, как в следующих примерах:
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");
}
c++
language-lawyer
object-lifetime
default-arguments
reference-binding
Ледяное сердце
источник
источник
std::string
собственным классом, чтобы вы могли отслеживать строительство и разрушение.Ответы:
В вашем коде оба
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
источник
Это не безопасно :
источник
std::string s2 = foo();
является действительным (в конце концов, никакие ссылки не передаются явно)?Это зависит от того, что вы делаете со строкой впоследствии.
Если ваш вопрос правильный мой код? тогда да, это так.
Из [dcl.fct.default] / 2
Таким образом, ваш код фактически эквивалентен:
Весь ваш код верен, но ни в одном из этих случаев продление срока службы ссылок отсутствует, поскольку возвращаемый тип является ссылкой.
Поскольку вы вызываете функцию с временным значением, время жизни возвращаемой строки не будет расширять оператор.
Ваш пример с
s2
хорошо, так как вы копируете (или перемещаете) из временного до конца satement.s3
имеет ту же проблему, чемs1
.источник