Extending C++ ostream

Extending C++ ostream

本文关键字:ostream C++ Extending      更新时间:2023-10-16

我正在尝试通过扩展std::streambuf来了解有关C++ I/O流库工作原理的更多信息。 作为一个学习实验,我的目标是简单地创建一个自定义流,将所有输出定向到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";
}

这似乎有效,因为它打印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
}

我想问题是xsputn不处理单个字符插入。 (我猜sputc不会在内部打电话给xsputn? 但是,查看std::streambuf中的虚拟受保护函数列表,我没有看到任何我应该覆盖的处理单个字符插入的函数。

那么,我该如何才能做到这一点呢?

单字符输出由 overflow 处理。以下是在xsputn执行实际输出时如何在xsputn方面实现overflow

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();
    }
}