[英]How does this printing code work?
我在某处找到了此代码。 它以奇怪的方式在屏幕上显示“ 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>
(您猜对了printbuf()
,该函数允许我们将输出流缓冲区用作输出迭代器 。
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_iterator
将它们写入std::cout
std::ostreambuf_iterator
( it
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.