这个打印代码是如何工作的

How does this printing code work?

本文关键字:工作 何工作 打印 代码      更新时间:2023-10-16

我在某处找到了这段代码。它在屏幕上打印"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);
}

我们有一个类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()是一个函数,它接受范围类X的实例,以及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实例将字符串缓冲区视为迭代器范围。然后,我们将该范围复制到输出流缓冲区迭代器(也是隐式构造的)std::cout

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

其效果是,我们在缓冲区中的每个字符上循环,并将其复制到标准输出。

printbuf(&buf, std::cout);

传递std::stringbuf*作为第一参数导致X的隐式构造与printbuf() 匹配

对于第二个参数如果发生构造,则从std::cout(std::ostream)创建std::ostreambuf_iterator<char>的实例

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

在printbuf中,foreach循环(基于循环的范围)使用X::begin()X::end()循环该包装的std::stringbuf中的所有字符,并通过std::ostreambuf_iteratorit)将它们写入std::cout