我试图通过扩展来了解有关C++ I/O流库的工作原理的更多信息std::streambuf.作为一个学习实验,我的目标是简单地创建一个自定义流,将所有输出定向到std::cerr.看起来很简单:
#include <iostream>
using namespace std;
class my_ostreambuf : public std::streambuf
{
public:
protected:
std::streamsize xsputn(const char * s, std::streamsize n)
{
std::cerr << "Redirecting to cerr: " << s << std::endl;
return n;
}
};
int main()
{
my_ostreambuf buf;
std::ostream os(&buf);
os << "TEST";
}
Run Code Online (Sandbox Code Playgroud)
这似乎有效,因为它打印Redirecting to cerr: TEST.问题是当单个字符(而不是字符串)通过插入流时,它不起作用.例如:std::ostream::sputc
int main()
{
my_ostreambuf buf;
std::ostream os(&buf);
os << "ABC"; // works
std::string s("TEST");
std::copy(s.begin(), s.end(), std::ostreambuf_iterator<char>(os)); // DOESN'T WORK
}
Run Code Online (Sandbox Code Playgroud)
我猜的问题是xsputn不处理单个字符插入.(我想sputc不会调用xsputn内部?)不过,看在的虚保护功能列表中std::streambuf,我没有看到,我应该重写处理单个字符插入任何功能.
那么,我该怎样才能做到这一点?
单字符输出由overflow.处理.这里是你将如何实现overflow来讲xsputn,如果xsputn不实际的输出:
int_type overflow(int_type c = traits_type::eof())
{
if (c == traits_type::eof())
return traits_type::eof();
else
{
char_type ch = traits_type::to_char_type(c);
return xsputn(&ch, 1) == 1 ? c : traits_type::eof();
}
}
Run Code Online (Sandbox Code Playgroud)