Est-il correct de renvoyer la valeur de l'argument par défaut par référence const comme dans les exemples ci-dessous:
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");
}
std::string
par une classe de votre choix pour suivre la construction et la destruction.Réponses:
Dans votre code, les deux
s1
ets3
sont des références pendantes.s2
ets4
sont ok.Dans le premier appel, l'
std::string
objet vide temporaire créé à partir de l'argument par défaut sera créé dans le contexte de l'expression contenant l'appel. Par conséquent, il mourra à la fin de la définition des1
, ce qui laisses1
pendant.Dans le deuxième appel, l'
std::string
objet temporaire est utilisé pour initialisers2
, puis il meurt.Dans le troisième appel, le littéral de chaîne
"s"
est utilisé pour créer unstd::string
objet temporaire et qui meurt également à la fin de la définition des3
, laissants3
pendre.Dans le quatrième appel, l'
std::string
objet temporaire avec valeur"s"
est utilisé pour initialisers4
puis il meurt.Voir C ++ 17 [class.temporary] /6.1
la source
Ce n'est pas sûr :
la source
std::string s2 = foo();
c'est valide (après tout, aucune référence n'est transmise explicitement)?Cela dépend ensuite de ce que vous faites avec la chaîne.
Si votre question est, mon code est-il correct? alors oui c'est ça.
Depuis [dcl.fct.default] / 2
Votre code équivaut donc à:
Tout votre code est correct, mais il n'y a aucune extension de durée de vie de référence dans aucun de ces cas, car le type de retour est une référence.
Puisque vous appelez une fonction avec une valeur temporaire, la durée de vie de la chaîne renvoyée ne prolongera pas l'instruction.
Votre exemple avec
s2
est correct puisque vous copiez (ou déplacez) du temporaire avant la fin du satement.s3
a le même problème ques1
.la source