我有很多日志记录功能,现在接受ostringstream&
。我的目标是让他们能够接受一行编写的流,如下所示:
MyPrint( ostringstream() << "hello!" << endl);
我无法更改方法原型,因为我有很多必须仍然有用的遗留代码。我想将其更改为ostream&
,因为这是<<
的返回值类型。现在原型的形式如下:
void MyPrint( <some parameters>, ostringstream& stream)
我在阅读此处c++ stringstream to ostream to string后建议的更改是(让我们忽略其他参数):
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
编辑:澄清了我不能破坏的旧原型。
答案 0 :(得分:1)
返回类型&lt;&lt;可以是你想要的任何东西 - 只需创建自己的类型。唯一真正的限制是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);
}
在线演示 - &gt; http://ideone.com/Gm7Cnc
答案 1 :(得分:1)
由于您没有得到太多回复,我发布了相同的问题并进行了一些更改。幸运的是,我得到了正确答案。请看HERE。
基本上std::stringbuf
的{{1}}不支持读取,因为传递的标志不同,因为您没有得到任何输出。