2016-03-01 36 views
16

consideri il seguente esempio:È legale spostare il membro .str() di uno stringstream?

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

Se dovessi ritornare risultato, invece di result.str() sarebbe diventato automaticamente un rvalue. Non così la stringa contenuta nel risultato (presumo). La mia aspettativa è che sia copiato e la copia restituita come valore.

Quindi la mia domanda è qui, è legale:

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

Vorrei assumere è, aspettandosi il flusso di essere lasciato con una stringa vuota valida. Ma non mi sento abbastanza sicuro per farlo davvero.

+10

La chiamata 'std :: move (e)' in un'istruzione return è un anti-pattern. L'espressione restituita è implicitamente trattata come un valore rval e comunque usando 'std :: move' inibisce copy-elision. – TartanLlama

+1

@TartanLlama non stai semplificando eccessivamente? Cosa accadrebbe se ci fosse una funzione "std :: string std :: ostringstream :: str() &&", non sarebbe il modo migliore per lasciare la funzione a "return std :: move (result) .str();"? – kamikaze

+0

@kamikaze Sì, come Baum dice che mi riferivo al modello in cui tutto ciò che hai nella dichiarazione di ritorno è 'std :: move (e)', dove 'e' è una espressione. – TartanLlama

risposta

20

std::ostream::str restituisce effettivamente una copia della stringa interna. Quindi la mossa è legale, ma non ha senso dato che result.str() è comunque un valore assoluto e quindi lo std::move non fa nulla di utile. Se mai, ostacola RVO, quindi non farlo. (Come @TartanLlama giustamente ha sottolineato nel suo comment, "Non spostare il valore di ritorno" vale in generale, non solo quando ritorno rvalues.)

In particolare, il std::move non influisce sulla stringa di oggetto interno il flusso.

+0

Era imbarazzante. Per qualche ragione ho pensato che restituisse un riferimento. – kamikaze

+1

@kamikaze In caso di dubbio o per ricontrollare consultare la [documentazione] (http://en.cppreference.com/w/cpp/io/basic_stringstream/str) – NathanOliver

+1

@kamikaze Questo è ciò che abbiamo [documentazione] (http://en.cppreference.com/w/cpp/io/basic_ostringstream/str) per. ;) –