2

Je lis quelque chose sur la résolution de surcharge et j'ai trouvé quelque chose qui me dérange ... Dans le code suivant:Promotion intégrale lors de la transmission et du renvoi d'argument par référence?

int const& MaxValue(int const& a, int const& b) 
{ 
    return a > b ? a : b; 
} 

void SomeFunction() 
{ 
    short aShort1 = 3; 
    short aShort2 = 1; 
    int const & r2 = MaxValue(aShort1, aShort2); // integral promotion 
    //is it safe to pass r2 around before function SomeFunction completes 
    // CallSomeOtherFunctionThatCallsSomethingElse(r2); 

} 

Ma compréhension est que deux années int temporaires sont créés et ils sont alloués sur la pile appartenant à SomeFunction. Donc, lorsque MaxValue retourne, r2 référençant à l'une de ces variables temporaires (dans ce cas, celle qui contient la valeur 3). Ainsi, il devrait être prudent de faire circuler r2.

La question est, si ma compréhension est bonne, est-ce un comportement standard (s'il vous plaît vérifier)? Si non, veuillez expliquer ce qui se passe dans le code ci-dessus.

Merci beaucoup

Répondre

2

Réponse courte: il est dangereux.

Les garanties standard qu'une variable temporaire peut être lié à une référence constante auquel cas la durée de vie des se dilate temporaires à la durée de vie de la référence liée. Le problème dans votre cas particulier est quelle référence lie réellement le temporaire.

Lorsque vous appelez MaxValue(s1, s2), deux variables temporaires de type int sont créés et liés aux arguments des paramètres a et b dans MaxValue. Cela signifie que la durée de vie de ces temporaires est étendue à l'achèvement de la fonction. Maintenant, dans la déclaration de retour de votre fonction, vous prenez une deuxième référence à l'un des temporaires et cette deuxième référence ne prolongera pas la durée de vie. r2 ne prolongera pas la durée de vie de l'objet, et vous avez une référence qui pend.

Notez qu'en raison de la compilation séparée, le compilateur ne peut pas savoir peut-être à l'extérieur de MaxValue si la référence retournée est à l'un des arguments ou à un tout autre objet qui n'est pas temporaire:

int const & OtherMaxValue(int const & a, int const & b) { 
    static int value = 0; 
    value = (a > b? a : b); 
    return value; 
} 

Il est donc impossible de deviner si l'une ou l'autre de la durée de vie temporaire doit être étendue.En remarque, pour les petits objets (comme tous les types entiers), le passage par référence peut être pire que le passage par la valeur. Il existe également un modèle std::max qui implémente cette fonctionnalité.

3

Oui, votre compréhension est bonne et c'est un comportement standard.

Sauf ceci:

Ainsi, est doit être sûr de passer autour r2.

que je ne comprends pas.

// EDIT

Vous devez utiliser des pointeurs au lieu de références ici pour obtenir le même mais sans le problème. L'utilisation de l'adresse d'un argument passé par la référence const est OK uniquement dans la fonction car elle peut pointer vers la copie locale d'un objet.

+0

Je suis d'accord avec votre réponse, et la qualification pour cela. –

4

Bienvenue à pourquoi les moulages implicites sucent. Vous avez maintenant une référence à un temporaire, qui a été détruit. J'espère que tu ne voulais rien faire avec ça.

1

Vous devriez retourner et passer en valeur pour les types simples.

Questions connexes