2016-03-01 3 views
16

Prenons l'exemple suivant:Est-il légal de déplacer le membre .str() d'un stringstream?

#include <sstream> 
template <typename T> 
inline std::string to_string(T const & op) { 
    std::ostringstream result; 
    result << op; 
    return result.str(); 
} 

Si je devais retourner résultat, au lieu de result.str() il deviendrait automatiquement un rvalue. Pas si la chaîne contenue dans le résultat (je suppose). Mon attente est qu'il est copié et la copie retournée comme une valeur.

Donc, ma question est ici, est-il légal de:

return std::move(result.str()); 

Je suppose qu'il est, en attendant le flux à gauche avec un valide, une chaîne vide. Mais je ne me sens pas assez certain pour le faire.

+10

L'appel de 'std :: move (e)' dans une instruction return est un anti-pattern. L'expression retournée est implicitement traitée comme un rvalue de toute façon et l'utilisation de 'std :: move' inhibe l'élision de la copie. – TartanLlama

+1

@TartanLlama ne simplifiez-vous pas? Que se passerait-il s'il y avait une fonction "std :: string std :: ostringstream :: str() &&", ne serait pas le meilleur moyen de quitter la fonction "return std :: move (result) .str();" – kamikaze

+0

@kamikaze Oui, comme Baum dit que je faisais référence au modèle où tout ce que vous avez dans votre déclaration de retour est 'std :: move (e)', où 'e' est une expression. – TartanLlama

Répondre

20

std::ostream::str renvoie en effet une copie de la chaîne interne. Donc le mouvement est légal, mais cela n'a aucun sens car result.str() est de toute façon un rvalue et donc le std::move ne sert à rien. Si quoi que ce soit, cela empêche RVO, alors ne le faites pas. (Comme @TartanLlama correctement souligné dans son comment, « Ne déplacez pas la valeur de retour » est également vrai en général, pas seulement lors du retour rvalues.)

En particulier, le std::move ne touche pas l'objet chaîne interne le flux.

+0

C'était embarrassingly facile. Pour une raison quelconque, j'ai pensé qu'il renvoie une référence. – kamikaze

+1

@kamikaze En cas de doute ou de contre-vérification, consultez le [documentation] (http://fr.cppreference.com/w/cpp/io/basic_stringstream/str) – NathanOliver

+1

@kamikaze C'est ce que nous avons [documentation] (http://en.cppreference.com/w/cpp/io/basic_ostringstream/str) pour. ;) –