Załóżmy, że mam funkcję, która pobiera ostream &
parametr o
i zapisuje do tego ostream. Implementacja operator <<
byłaby dobrym przykładem.Czy powinienem utworzyć tymczasowy ostream, używając innego strumienia?
ostream& operator << (ostream& o, const MyThing& t)
{
// ... interesting code here ...
return o;
}
W ramach tej funkcji mogę chcieć określić opcje formatowania w strumieniu. Na przykład, mogę chcieć, aby liczba była drukowana w postaci heksadecymalnej, bez względu na konfigurację o
, gdy jest przekazywana do funkcji.
Po drugie, mógłbym chcieć mieć założenia dotyczące aktualnych flag formatowania. Na przykład dobrze byłoby móc założyć, że liczby zostały sformatowane jako dziesiętne, o ile nie zażądam inaczej.
Wreszcie, do czasu wyjścia z funkcji chcę, aby opcje formatowania na o
były takie same, jak przed wywołaniem funkcji, aby wyglądały niezmiennie dla osoby dzwoniącej. Jest to po prostu kwestia uprzejmości dla osoby dzwoniącej.
Do tej pory udało mi się osiągnąć to poprzez stworzenie lokalnej ostringstream
wewnątrz funkcji, czyniąc całą moją pracę na ten temat (w tym ustawiania opcji formatowania), a wysłaniem .str()
do o
po zakończeniu funkcji. Pytanie StackOverflow here sugeruje, że ludzie sprytniejsi ode mnie stosują to samo podejście. Jednak przeszkadza mi to, że przechowuję tak dużo danych w ostrych strumieniach, które być może zostały wcześniej wysłane do wyjścia (łańcuchy mogą stać się całkiem duże).
Mam dwa pytania:
1) jest to legalne, idiomatyczne, dobrą formę, itp aby utworzyć tymczasowy (stack based) ostream wokół o.rdbuf()
i wykonywać moją pracę na tym ostream? Moje własne testy i strona pod adresem cppreference.com sugerują, że mogę.
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) Czy istnieje inny, lepszy sposób, którego nie rozważałem?
Połączenia te najlepiej znajdować się w konstruktora i destruktora jakiś obiekt oparty na stosie. Zakładam, że to właśnie robią klasy Boost. – peterpi