Предположим, что у меня есть функция, которая принимает параметр ostream &
o
и записывает этот поток. Реализация operator <<
будет хорошим примером.
ostream& operator << (ostream& o, const MyThing& t)
{
// ... interesting code here ...
return o;
}
Внутри функции я могу указать параметры форматирования в потоке. Например, мне может потребоваться, чтобы число было напечатано как hex, независимо от того, как o
настроен, когда он передается функции.
Во-вторых, я могу захотеть сделать предположения о текущих флагах форматирования. Например, было бы неплохо иметь возможность предположить, что числа были отформатированы как десятичные, если я не попрошу иначе.
Наконец, к моменту выхода функции я хочу, чтобы параметры форматирования на o
были такими же, как они были до того, как была вызвана функция, чтобы они не изменились для вызывающего. Это просто вопрос вежливости вызывающему.
До сих пор я достиг этого, создав локальную ostringstream
внутри функции, выполнив всю свою работу над этим (включая параметры форматирования параметров) и отправив .str()
в o
в конце функции, Вопрос StackOverflow здесь говорит о том, что люди умнее меня используют один и тот же подход.. Однако мне мешает, что я храню столько данных в ostringstreams, которые, возможно, могут быть отправлены на выход раньше (строки могут стать довольно большими).
У меня есть два вопроса:
1) Является ли это законной, идиоматической, хорошей формой и т.д. создавать временный (основанный на стеке) поток вокруг o.rdbuf()
и выполнять мою работу над этим ostream? Мои собственные тесты и страница cppreference.com показывают, что я могу.
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) Есть ли другой, лучший способ, который я не рассматривал?