2015-05-05 13 views
15

Ho notato qualcosa durante il tentativo di utilizzare l'oggetto stringstream. Ecco un esempio di inutile per spiegare questo:std :: stringstream e il metodo str

stringstream ss ; 
ss << "my string" ; 
cout << ss.str() << endl ; 

non equivale a

cout << (stringstream() << "my string").str() << endl ; 

Questo porta ad un errore di compilazione lamentando che ‘classe std :: basic_ostream’ non ha alcun membro denominato ‘str’.

Non riesco a spiegarlo facilmente. Questo non è fondamentale per la mia applicazione, ma sono abbastanza sicuro che questo è nascondere un trucco C++ interessante da comprendere.

Nota: sto usando gcc con C++ 14

+0

Soluzione: 'static_cast (stringstream() <<" my string "). Str()'. Oppure, sai, usa la variabile chiamata. – Potatoswatter

+0

Alla fine era ovvio, mi ero appena sbagliato nel cercare di spiegarlo. – Falco

risposta

22

Il operator<< è non definito per std::stringstream, ma per la sua classe base std::ostream, quindi esso non restituisce un riferimento alla std::stringstream e quindi la metodo str() (che è un metodo di std::stringstream) non trovato.

Tecnicamente, quanto sopra è in realtà std::basic_stringstream<CharT,Traits> e std::basic_ostream<CharT,Traits>, ma si ottiene l'idea :)

6

Il problema di questo:

cout << (stringstream() << "my string").str() << endl; 

E 'che l'espressione stringstream() << "my string" restituisce un oggetto std::ostream&, non un std::stringstream.

È possibile rimediare a questa definendo alcuni sovraccarichi appropriate:

template<typename Type> 
std::stringstream& operator<<(std::stringstream& ss, const Type& type) 
{ 
    static_cast<std::ostream&>(ss) << type; 
    return ss; 
} 

template<typename Type> 
std::stringstream& operator<<(std::stringstream&& ss, const Type& type) 
{ 
    static_cast<std::ostream&>(ss) << type; 
    return ss; 
} 

template<typename Type> 
std::stringstream& operator>>(std::stringstream& ss, Type& type) 
{ 
    static_cast<std::istream&>(ss) >> type; 
    return ss; 
} 

template<typename Type> 
std::stringstream& operator>>(std::stringstream&& ss, Type& type) 
{ 
    static_cast<std::istream&>(ss) >> type; 
    return ss; 
} 

Ora, quando si utilizzano gli operatori << e >> su un oggetto std::stringstream, chiamerà questi sovraccarichi e restituirà un std::stringstream& in modo da poter usa la sua interfaccia direttamente.