2015-03-29 5 views
3

Dans mon code, j'ai une fonction qui construit une chaîne à partir d'une donnée et la renvoie ensuite. Cette chaîne n'est utilisée nulle part ailleurs, donc il est sûr pour le côté récepteur d'utiliser move-assignment ou move-initialization.Renvoie la référence rvalue par rapport au retour par la valeur dans le type de retour de la fonction

std::string ReadString(...) { 
    ... 
    return std::string(...) 
} 

C'est essentiellement ce que j'ai. Y at-il un quelconque intérêt à rendre la fonction return type std :: string & &, puisque la valeur retournée est une valeur r?

std::string&& ReadString(...) { 
    ... 
    return std::string(...) 
} 

Ma préoccupation est qu'il pourrait y avoir une copie excédentaire étant faite lorsque nous revenons à notre chaîne, et qu'il peut être atténué en faisant le type de retour une référence rvalue.

Je soupçonne que le compilateur peut également être capable d'optimiser pour ces scénarios, cependant, je ne suis pas sûr. Donc, la question est - est-il utile de faire du type de retour une référence de référence dans ce cas et pourquoi? Aussi, s'il n'y en a pas, alors quelles sont les applications possibles pour les fonctions renvoyant des références rvalue?

Merci.

+1

Habituellement, il est OK de retourner en valeur. Laissez la copie d'élision au compilateur dans ce cas. –

+1

Le compilateur peut gérer cela très bien. Il peut même écrire la chaîne sans temporaire directement dans la variable que vous lui attribuez. Parce que la valeur que vous renvoyez est déjà un objet temporaire, il est toujours possible d'en partir. – Otomo

+0

Merci à tous, c'est exactement ce que je me demandais. Cela clarifie ma confusion. –

Répondre

7

Renvoyer une référence à un objet sur le point d'être détruit est toujours faux: l'objet référencé sera détruit avant de pouvoir être utilisé sous quelque forme que ce soit. Faire de la référence une référence rvalue ne change rien à cela, il suffit de retourner une compilation temporaire. Notez que le retour d'une chaîne temporaire par valeur entraînera probablement l'élision de la copie, c'est-à-dire que l'objet sera probablement construit directement à l'emplacement où il est utilisé. Si cela ne se produit pas, l'objet sera déplacé s'il existe un constructeur de déplacement pour le type de retour (pour std::string). Notez qu'il en va de même lorsque vous renvoyez une variable locale de fonction au lieu du temporaire.

+0

Merci pour la réponse, cela éclaircit ma confusion. Je n'étais pas tout à fait sûr si les compilateurs optimisés pour cela. –