简体   繁体   English

此打印代码如何工作?

[英]How does this printing code work?

I found this code somewhere. 我在某处找到了此代码。 It prints "abcd" to the screen but in a weird way. 它以奇怪的方式在屏幕上显示“ abcd”。 I would like someone to tell me how it works: 我想有人告诉我它是如何工作的:

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

We have a class X which encapsulates an istreambuf_iterator <char> . 我们有一个X类,它封装了istreambuf_iterator <char> This is an iterator type which allows us to treat a stream buffer as an iterator range for standard algorithms. 这是一个迭代器类型,它使我们可以将流缓冲区视为标准算法的迭代器范围。

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

The class is constructible from a pointer to a stream buffer instance. 该类可以从指向流缓冲区实例的指针构造。

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

It exposes begin() and end() member functions to allow it to be used with the range-based for loop. 它公开了begin()end()成员函数,以使其可与基于范围的for循环一起使用。

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

printbuf() is a function which accepts an instance of our range class X , as well as an ostreambuf_iterator <char> , which—you guessed it—allows us to use an output stream buffer as an output iterator . printbuf()是一个函数,它接受范围类X的实例以及ostreambuf_iterator <char> (您猜对了printbuf() ,该函数允许我们将输出流缓冲区用作输出迭代器

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

So we iterate over every character in the input range. 因此,我们遍历了输入范围内的每个字符。

    for (auto c : x)
    {

If you haven't dealt with output iterators before, you can think of them as an object resembling a pointer, to which you write values using dereference and assignment. 如果您以前从未处理过输出迭代器,则可以将它们视为类似于指针的对象,可以使用取消引用和赋值向其写入值。 back_insert_iterator is a commonly used output iterator, for building containers—you usually construct it using back_inserter . back_insert_iterator是用于构建容器的常用输出迭代器-您通常使用back_inserter构造它。 But I digress. 但是我离题了。

We copy each character to the output iterator. 我们将每个字符复制到输出迭代器。

        *it = c;
    }
}

int main()
{

Here we construct a string buffer, which is both an input and output stream buffer. 在这里,我们构造了一个字符串缓冲区,它既是输入流缓冲区又是输出流缓冲区。 We only use the input capability in this example. 在此示例中,我们仅使用输入功能。

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

Now we use an implicitly-constructed X instance to treat the string buffer as an iterator range. 现在,我们使用隐式构造的X实例将字符串缓冲区视为迭代器范围。 Then we copy that range to an output stream buffer iterator—also implicitly constructed—to std::cout . 然后,我们将该范围复制到一个输出流缓冲区迭代器(也隐式构造)到std::cout

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

The effect is that we're looping over each character in the buffer and copying it to standard output. 结果是我们遍历了缓冲区中的每个字符,并将其复制到标准输出。

printbuf(&buf, std::cout);

Passing std::stringbuf* as the first paramter causes an implicit construction of X to match printbuf() 传递std::stringbuf*作为第一个参数会导致X的隐式构造与printbuf()匹配

And also for the second parameter, an implicit contruction occurs, an instance of std::ostreambuf_iterator<char> is created from std::cout (std::ostream) 而且对于第二个参数,发生隐式构造,从std::cout (std :: ostream)创建std::ostreambuf_iterator<char>的实例。

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

In printbuf, the foreach loop (range based for loop) uses X::begin() and X::end() to loop over all characters in that wrapped std::stringbuf and writes them to std::cout via the std::ostreambuf_iterator ( it ) 在printbuf中,foreach循环(基于范围的循环)使用X::begin()X::end()循环包装该std::stringbuf所有字符,并通过std::ostreambuf_iterator将它们写入std::cout std::ostreambuf_iteratorit

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM