ano*_*non 31 c++ iostream overloading manipulators endl
我想定义一个类,MyStream以便:
MyStream myStream;
myStream << 1 << 2 << 3 << std::endl << 5 << 6 << std::endl << 7 << 8 << std::endl;
Run Code Online (Sandbox Code Playgroud)
给出输出
[blah]123
[blah]56
[blah]78
Run Code Online (Sandbox Code Playgroud)
基本上,我想在前面插入一个"[blah]",然后在每次非终止 后插入std::endl?
这里的困难不是逻辑管理,而是检测和重载处理std::endl.有一种优雅的方式来做到这一点?
谢谢!
编辑:我不需要有关逻辑管理的建议.我需要知道如何检测/过载打印std::endl.
Mar*_*ork 32
您需要做的是编写自己的流缓冲区:
当刷新流缓冲区时,输出前缀字符和流的内容.
以下是有效的,因为std :: endl会导致以下情况.
1)在流中添加'\n'.
2)在流上调用flush()
2a)这将调用流缓冲区上的pubsync().
2b)这将调用虚方法sync()
2c)覆盖此虚方法以执行所需的工作.
#include <iostream>
#include <sstream>
class MyStream: public std::ostream
{
// Write a stream buffer that prefixes each line with Plop
class MyStreamBuf: public std::stringbuf
{
std::ostream& output;
public:
MyStreamBuf(std::ostream& str)
:output(str)
{}
~MyStreamBuf() {
if (pbase() != pptr()) {
putOutput();
}
}
// When we sync the stream with the output.
// 1) Output Plop then the buffer
// 2) Reset the buffer
// 3) flush the actual output stream we are using.
virtual int sync() {
putOutput();
return 0;
}
void putOutput() {
// Called by destructor.
// destructor can not call virtual methods.
output << "[blah]" << str();
str("");
output.flush();
}
};
// My Stream just uses a version of my special buffer
MyStreamBuf buffer;
public:
MyStream(std::ostream& str)
:std::ostream(&buffer)
,buffer(str)
{
}
};
int main()
{
MyStream myStream(std::cout);
myStream << 1 << 2 << 3 << std::endl << 5 << 6 << std::endl << 7 << 8 << std::endl;
}
> ./a.out
[blah]123
[blah]56
[blah]78
>
Run Code Online (Sandbox Code Playgroud)
Tim*_*mbo 18
您的MyStream类的重载运算符必须设置previous-printed-token-was-endl标志.
然后,如果打印下一个对象,则[blah]可以将其插入其前面.
std::endl是一个函数接受并返回一个引用std::ostream.要检测它已移入您的流,您必须operator<<在您的类型和这样的函数之间重载:
MyStream& operator<<( std::ostream&(*f)(std::ostream&) )
{
std::cout << f;
if( f == std::endl )
{
_lastTokenWasEndl = true;
}
return *this;
}
Run Code Online (Sandbox Code Playgroud)