Est-ce que l'exemple suivant (artificiel) est correct ou est-ce un comportement non défini:
// undefined behavior?
const auto& c = SomeClass{};
// use c in code later
const auto& v = c.GetSomeVariable();
la source
Est-ce que l'exemple suivant (artificiel) est correct ou est-ce un comportement non défini:
// undefined behavior?
const auto& c = SomeClass{};
// use c in code later
const auto& v = c.GetSomeVariable();
C'est sûr. Const ref prolonge la durée de vie des temporaires. La portée sera la portée de la référence const.
La durée de vie d'un objet temporaire peut être étendue en se liant à une référence const lvalue ou à une référence rvalue (depuis C ++ 11), voir l' initialisation de la référence pour plus de détails.
Chaque fois qu'une référence est liée à un temporaire ou à un de ses sous-objets, la durée de vie du temporaire est étendue pour correspondre à la durée de vie de la référence, avec les exceptions suivantes :
- une liaison temporaire à une valeur de retour d'une fonction dans une instruction de retour n'est pas étendue: elle est détruite immédiatement à la fin de l'expression de retour. Une telle fonction renvoie toujours une référence pendante.
- un lien temporaire à un membre de référence dans une liste d'initialisation de constructeur persiste uniquement jusqu'à ce que le constructeur se termine, pas tant que l'objet existe. (note: une telle initialisation est mal formée à partir de DR 1696).
- une liaison temporaire à un paramètre de référence dans un appel de fonction existe jusqu'à la fin de l'expression complète contenant cet appel de fonction: si la fonction renvoie une référence, qui survit à l'expression complète, elle devient une référence pendante.
- une liaison temporaire à une référence dans l'initialiseur utilisé dans une nouvelle expression existe jusqu'à la fin de l'expression complète contenant cette nouvelle expression, pas aussi longtemps que l'objet initialisé. Si l'objet initialisé survit à l'expression complète, son membre de référence devient une référence pendante.
- une liaison temporaire à une référence dans un élément de référence d'un agrégat initialisé à l'aide de la syntaxe d'initialisation directe (parenthèses) par opposition à la syntaxe d'initialisation de liste (accolades) existe jusqu'à la fin de l'expression complète contenant l'initialiseur.
struct A { int&& r; }; A a1{7}; // OK, lifetime is extended A a2(7); // well-formed, but dangling reference
En général, la durée de vie d'un temporaire ne peut pas être prolongée davantage en la "transmettant": une deuxième référence, initialisée à partir de la référence à laquelle le temporaire était lié, n'affecte pas sa durée de vie.
comme @Konrad Rudolph l'a souligné (et voir le dernier paragraphe ci-dessus):
"Si
c.GetSomeVariable()
renvoie une référence à un objet local ou une référence indiquant qu'il prolonge lui-même la durée de vie d'un objet, l'extension à vie ne se déclenche pas"
c.GetSomeVariable()
renvoie une référence à un objet local ou une référence indiquant qu'il prolonge lui-même la durée de vie d'un objet, l'extension de durée de vie ne démarre pas .Il ne devrait pas y avoir de problème ici, grâce à l' extension de la durée de vie . L'objet nouvellement construit survivra jusqu'à ce que la référence soit hors de portée.
la source
Oui, cela est parfaitement sûr: la liaison à un
const
référence étend la durée de vie du temporaire à la portée de cette référence.Notez cependant que le comportement n'est pas transitif . Par exemple, avec
cc
se balance.la source
C'est sûr.
la source
Il est sûr dans ce cas spécifique. Notez cependant que tous les temporaires ne sont pas sécurisés à capturer par référence const ... par exemple
La référence obtenue pour
z
n'est PAS sûre à utiliser car l'instance temporaire sera détruite à la fin de l'expression complète, avant d'atteindre l'printf
instruction. La sortie est:la source