Supponiamo che io abbia una funzione che prende un parametro o
e scrive in tale ostream. Un'implementazione operator <<
sarebbe un buon esempio.Devo creare un ostream temporaneo usando streambuf di un altro?
ostream& operator << (ostream& o, const MyThing& t)
{
// ... interesting code here ...
return o;
}
All'interno della funzione, potrei voler specificare le opzioni di formattazione sul flusso. Ad esempio, potrei desiderare che un numero venga stampato come esadecimale, indipendentemente da come sia configurato lo o
quando viene passato alla funzione.
In secondo luogo, potrei voler fare ipotesi sulle attuali flag di formattazione. Ad esempio, sarebbe bello poter supporre che i numeri siano stati formattati come decimali a meno che non chieda il contrario.
Infine, quando termina la funzione, desidero che le opzioni di formattazione su o
siano le stesse di prima della chiamata alla funzione, in modo tale da apparire invariate al chiamante. Questa è semplicemente una questione di cortesia per il chiamante.
Fino ad ora ho raggiunto questo attraverso la creazione di un locale ostringstream
all'interno della funzione, facendo tutto il mio lavoro su quella (compresa l'impostazione delle opzioni di formattazione), e l'invio del .str()
-o
al termine della funzione. La domanda StackOverflow here suggerisce che le persone più intelligenti di me adottano lo stesso approccio. Tuttavia, mi dà fastidio il fatto che tengo così tanti dati in strings che potrebbero forse essere inviati all'output in precedenza (le stringhe possono diventare piuttosto grandi).
Ho due domande:
1) E 'legale, idiomatica, buona forma, ecc di creare un (stack based) ostream temporaneo intorno o.rdbuf()
e fare il mio lavoro su quel ostream? I miei test e la pagina allo cppreference.com sembrano suggerire che posso.
ostream& operator << (ostream& o_, const MyThing& t)
{
ostream o (o_.rdbuf());
// write stuff to "o",
// setting formatting options as I go.
return o_; // Formatting on the parameter ostream o_ unchanged.
}
2) Esiste un altro modo migliore che non ho considerato?
Quelle chiamate sarebbe meglio metterlo nel costruttore e distruttore di qualche oggetto basato su stack. Immagino sia quello che fanno le classi Boost. – peterpi