我有很多日志记录功能,它们现在接受 ostringstream&
。我的目标是让他们能够接受一行写入的流,如下所示:
MyPrint( ostringstream() << "hello!" << endl);
我无法大幅更改方法原型(prototype),因为我有很多必须仍然有效的遗留代码。我想把它改成ostream&
因为那是<<
的返回值类型。现在原型(prototype)的形式如下:
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
编辑:澄清了我不能破坏的旧原型(prototype)。
最佳答案
<< 的返回类型可以是您想要的任何类型 - 只需创建您自己的类型即可。唯一真正的限制是 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
关于c++ - 尝试从 ostream 打印但打印空白,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18248305/