5

を拡張することで、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";
}

が出力されるため、これはうまくいくよう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呼び出されないのでしょうか?) しかし、 の仮想保護された関数のリストに目を通すと、1 文字の挿入を処理する、オーバーライドするはずの関数が見つかりません。xsputnstd::streambuf

では、どうすればこれを達成できますか?

4

1 に答える 1

5

1 文字の出力は によって処理されoverflowます。実際の出力を行うかどうかoverflowに関して実装する方法は次のとおりです。xsputnxsputn

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();
    }
}
于 2012-06-06T20:33:11.160 に答える