reimpostare uno stringstream


86

Come faccio a "resettare" lo stato di uno stringstream a quello che era quando l'ho creato?

int firstValue = 1;
int secondValue = 2;

std::wstringstream ss;

ss << "Hello: " << firstValue;

std::wstring firstText(ss.str());

//print the value of firstText here


//How do I "reset" the stringstream here?
//I would like it behave as if I had created
// stringstream ss2 and used it below.


ss << "Bye: " << secondValue;

std::wstring secondText(ss.str());

//print the value of secondText here

Risposte:


135

Questo è il modo in cui lo faccio di solito:

ss.str("");
ss.clear(); // Clear state flags.

Grazie; eseguire il debug del C ++ di qualcun altro e ne aveva bisogno per risolvere un errore di violazione di accesso che stavano ottenendo a causa della mancata esecuzione del metodo .clear (). Funzionava bene su una scatola Intel ma vomitava ogni volta su una macchina AMD.
Chris Townsend

3
Sfortunatamente clearnon resetta i manipolatori io. Esempio di test fallito: std :: stringstream ss; ss << "Hello" << std :: setw (15) << "World" << std :: setw (15); reset (ss); ss << "Hello World"; assert ("Hello World" == buf.str ()); // fallisce, riprende l'ultimo std :: setw
GameSalutes

9

farei

std::wstringstream temp;
ss.swap(temp);

Modifica: corretto l'errore segnalato da christianparpart e Nemo. Grazie.

PS: il codice precedente crea un nuovo oggetto stringstream nello stack e scambia tutto in ss con quelli nel nuovo oggetto.

Vantaggi:

  1. Garantisce ss che ora sarà in uno stato nuovo.
  2. Il nuovo oggetto viene creato in linea e nello stack, in modo che il compilatore possa facilmente ottimizzare il codice. Alla fine, sarà come resettare tutti ssi dati interni allo stato iniziale.

Di Più:

  1. Rispetto all'operatore di assegnazione: i metodi di scambio STL possono essere più veloci dell'operatore di assegnazione nei casi in cui il nuovo oggetto ha un buffer allocato nell'heap. In tal caso, l'operatore di assegnazione deve allocare il buffer per il nuovo oggetto, quindi PU essere necessario allocare un altro buffer per il vecchio oggetto e quindi copiare i dati dal buffer del nuovo oggetto al nuovo buffer del vecchio oggetto. È molto facile implementare uno scambio veloce, che scambia solo i puntatori dei buffer, ad esempio.

  2. C ++ 11. Ho visto un'implementazione dell'operatore di assegnazione dello spostamento che è più lenta dello scambio, sebbene possa essere risolto, ma probabilmente lo sviluppatore STL non vorrà lasciare un oggetto spostato con molti dati

  3. std::move()non garantisce che l'oggetto spostato venga svuotato. return std::move(m_container);non cancella m_container. Quindi dovrai farlo

    auto to_return (std :: move (m_container)); m_container.clear (); return to_return;

Che non può essere migliore di

auto to_return;
m_container.swap(to_return);
return to_return;

perché quest'ultimo garantisce che non copierà i buffer.

Quindi preferisco sempre swap()finché si adatta.


2
Dovresti spiegare perché lo faresti. Questo codice non è molto utile da solo.
Machavity

1
Sebbene questa risposta possa essere corretta, aggiungi qualche spiegazione. L'impartire la logica sottostante è più importante del semplice dare il codice, perché aiuta l'OP e altri lettori a risolvere da soli questo e altri problemi simili.
CodeMouse92

Mi piace la soluzione. È molto breve e lo stesso modello funziona praticamente per tutti i tipi di dati std.
martinus

1
Questa risposta non è del tutto corretta in quanto potresti non collegarti a una variabile temporanea, ovvero crei una variabile temporanea per scambiare il flusso di stringhe vuoto appena creato (temporaneamente) con quello esistente "ss". Non autorizzato.
christianparpart

Questo non comporta tutto il sovraccarico di costruire una locale, che si suppone dovrebbe evitare il ripristino dello stringstream?
tappi il

2

Basandosi sulla risposta sopra, dobbiamo anche ripristinare qualsiasi formattazione. In tutto stiamo ripristinando il contenuto del buffer, i flag di stato del flusso e qualsiasi formattazione ai valori predefiniti quando viene costruita una nuova istanza std :: stringstream.

void reset(std::strinstream& stream)
{
    const static std::stringstream initial;

    stream.str(std::string());
    stream.clear();
    stream.copyfmt(initial);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.