У меня есть много функций регистрации, которые сейчас принимают ostringstream&
, Моя цель — сделать так, чтобы они могли принимать поток, записанный в одну строку, примерно так:
MyPrint( ostringstream() << "hello!" << endl);
Я не могу значительно изменить прототип метода, так как у меня есть много устаревшего кода, который все еще должен работать. Я хочу изменить это на ostream&
потому что это тип возвращаемого значения <<
, Прямо сейчас прототипы имеют вид:
void MyPrint( <some parameters>, ostringstream& stream)
Мои предлагаемые изменения после прочтения здесь c ++ stringstream для вывода в строку, is (давайте проигнорируем другие параметры):
void MyPrint(ostream& stream)
{
stringstream ss;
ss << stream.rdbuf();
cout << "ss is:" << ss.str() << endl;
}
и работает следующая строка:
MyPrint(stringstream().flush() << "hello world!" << endl);
но это печатает пробел:
ostringstream oss;
oss << "hello world!" << endl;
MyPrint(oss);
(это бы на самом деле работал с stringstream
по какой-то причине)
Вторая форма должна работать, поскольку так написан мой старый код.
Кроме того, если бы я мог избежать необходимости писать что-то не элегантное, как stringstream().flush()
Я хотел бы решение, каждое решение в этой теме работает, если вы делаете
wrapper() << "string"
но не компилируется, если вы делаете
wrapper() << "string" << endl
РЕДАКТИРОВАТЬ: разъяснил о старых прототипах, которые я не должен ломать.
Тип возврата << может быть чем угодно — просто создайте свой собственный тип. Единственным реальным ограничением является то, что код Ostringstream должен работать. Поддержка endl и других манипуляторов тривиальна. Проверь это:
#include <iostream>
#include <sstream>
#include <iomanip>
struct MyStream
{
mutable std::ostringstream ss;
MyStream() {}
MyStream(std::ostringstream & oss) { ss << oss.str(); }
};
typedef std::ostream & (*manipulator_t) (std::ostream &);
const MyStream & operator << (const MyStream & s, manipulator_t m)
{
s.ss << m;
return s;
}
template <class T>
const MyStream & operator << (const MyStream & s, T v)
{
s.ss << v;
return s;
}
void MyPrint(const MyStream & s)
{
std::cout << "logged: " << s.ss.str();
}
int main()
{
MyPrint(MyStream() << "true && false == " << std::boolalpha << (true && false) << std::endl);
std::ostringstream oss;
oss << std::setw(22) << "Hello, World!" << std::endl;
MyPrint(oss);
}
Демо онлайн -> http://ideone.com/Gm7Cnc
Поскольку вы не получили много ответов, я опубликовал тот же вопрос с некоторыми изменениями. К счастью, я получил правильный ответ. Пожалуйста посмотри ВОТ.
В принципе std::stringbuf
из std::ostringstream
не поддерживает чтение, так как переданные флаги отличаются, из-за чего вы не получаете никакого вывода.