Ist es in Ordnung, den Wert des Standardarguments per const-Referenz wie in den folgenden Beispielen zurückzugeben:
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
Gefrorenes Herz
quelle
quelle
std::string
durch eine eigene Klasse, damit Sie den Bau und die Zerstörung verfolgen können.Antworten:
In Ihrem Code baumeln beide
s1
unds3
baumeln Referenzen.s2
unds4
sind ok.Beim ersten Aufruf wird das
std::string
aus dem Standardargument erstellte temporäre leere Objekt im Kontext des Ausdrucks erstellt, der den Aufruf enthält. Daher wird es am Ende der Definition von sterbens1
, wass1
baumeln lässt.Beim zweiten Aufruf wird das temporäre
std::string
Objekt zum Initialisieren verwendets2
und stirbt dann ab.Im dritten Aufruf wird das String-Literal
"s"
verwendet, um ein temporäresstd::string
Objekt zu erstellen , das ebenfalls am Ende der Definition von stirbts3
unds3
baumelt.Beim vierten Aufruf wird das temporäre
std::string
Objekt mit dem Wert"s"
zum Initialisieren verwendets4
und stirbt dann ab.Siehe C ++ 17 [class.temporary] /6.1
quelle
Es ist nicht sicher :
quelle
std::string s2 = foo();
gültig ist (schließlich wird kein Verweis explizit weitergegeben)?Es hängt davon ab, was Sie danach mit der Zeichenfolge machen.
Wenn Ihre Frage ist, ist mein Code korrekt?dann ist es ja.
Aus [dcl.fct.default] / 2
Ihr Code entspricht also effektiv:
Ihr gesamter Code ist korrekt, aber in keinem dieser Fälle gibt es eine Verlängerung der Referenzlebensdauer, da der Rückgabetyp eine Referenz ist.
Da Sie eine Funktion mit einer temporären Zeichenfolge aufrufen, verlängert die Lebensdauer der zurückgegebenen Zeichenfolge die Anweisung nicht.
Ihr Beispiel mit
s2
ist in Ordnung, da Sie vor dem Ende des Satements aus dem Temporären kopieren (oder verschieben).s3
hat das gleiche Problem alss1
.quelle