1

このコードはどこかで見つけました。画面に「abcd」と表示されますが、奇妙な方法で表示されます。誰かにそれがどのように機能するか教えてもらいたい:

#include <iostream>
#include <sstream>

class X
{
    typedef std::istreambuf_iterator<char> Iter;
    Iter it;
public:
    X(std::streambuf* p) : it(p) { }

    Iter begin()
        { return it; }
    Iter end()
        { return Iter(); }
};

void printbuf(X x, std::ostreambuf_iterator<char> it)
{
    for (auto c : x)
    {
        *it = c;
    }
}

int main()
{
    std::stringbuf buf("abcd", std::ios_base::in | std::ios_base::out);
    printbuf(&buf, std::cout);
}
4

2 に答える 2

4

Xをカプセル化するクラスがありますistreambuf_iterator<char>。これは、ストリーム バッファを標準アルゴリズムのイテレータ範囲として扱うことを可能にするイテレータ タイプです。

class X
{
    typedef std::istreambuf_iterator<char> Iter;
    Iter it;
public:

このクラスは、ストリーム バッファー インスタンスへのポインターから構築できます。

    X(std::streambuf* p) : it(p) { }

begin()およびメンバー関数を公開end()して、範囲ベースのforループで使用できるようにします。

    Iter begin()
        { return it; }
    Iter end()
        { return Iter(); }
};

printbuf()は、出力ストリーム バッファを出力 iteratorとして使用できるようにする とX同様に、range クラスのインスタンスを受け入れる関数です。ostreambuf_iterator<char>

void printbuf(X x, std::ostreambuf_iterator<char> it)
{

したがって、入力範囲内のすべての文字を反復処理します。

    for (auto c : x)
    {

出力イテレータをこれまで扱ったことがない場合は、逆参照と代入を使用して値を書き込むポインタに似たオブジェクトと考えることができます。back_insert_iteratorコンテナを構築するために一般的に使用される出力イテレータです。通常は を使用して構築しback_inserterます。しかし、私は脱線します。

各文字を出力反復子にコピーします。

        *it = c;
    }
}

int main()
{

ここでは、入力ストリーム バッファーと出力ストリーム バッファーの両方である文字列バッファーを作成します。この例では入力機能のみを使用します。

    std::stringbuf buf("abcd", std::ios_base::in | std::ios_base::out);

ここで、暗黙的に構築されたXインスタンスを使用して、文字列バッファーをイテレーター範囲として扱います。次に、その範囲を出力ストリーム バッファ イテレータ (暗黙的に構築されたもの) to にコピーしますstd::cout

    printbuf(&buf, std::cout);
}

その効果は、バッファ内の各文字をループし、それを標準出力にコピーすることです。

于 2013-08-24T20:39:49.577 に答える
2
printbuf(&buf, std::cout);

最初のパラメーターとして渡すstd::stringbuf*と、暗黙的な構造のX一致が発生しますprintbuf()

また、2 番目のパラメーターについても、暗黙的な構造が発生し、のインスタンスが(std::ostream)std::ostreambuf_iterator<char>から作成されます。std::cout

void printbuf(X x, std::ostreambuf_iterator<char> it)
{
    for (auto c : x)
    {
        *it = c;
    }
}

printbuf では、foreach ループ (範囲ベースの for ループ) はX::begin()andX::end()を使用して、ラップされたすべての文字をループし、 ( )経由std::stringbufで書き込みます。std::coutstd::ostreambuf_iteratorit

于 2013-08-24T20:37:10.910 に答える