C++ streambuf、ostream、ostreambuf、istream、istreambuf和相关迭代器

C++ streambuf、ostream、ostreambuf、istream、istreambuf和相关迭代器,c++,stl,stream,iterator,buffer,C++,Stl,Stream,Iterator,Buffer,我想一定有人问了这些问题,所以请耐心听我说 我们考虑下面的动物: 奥斯特雷姆 峡流 流 streambuf 根据本杰明的观察,这个不属于这里。 斯特林布夫 以及以下迭代器: std::string line; // load line. std::stringstream linestream(line); std::istream_iterator<int> lineIterator(linestream); ostre

我想一定有人问了这些问题,所以请耐心听我说

我们考虑下面的动物:

奥斯特雷姆 峡流 流 streambuf 根据本杰明的观察,这个不属于这里。 斯特林布夫 以及以下迭代器:

std::string                  line; // load line.
std::stringstream            linestream(line);
std::istream_iterator<int>   lineIterator(linestream);
ostream_迭代器 ostreambuf_迭代器 istream_迭代器 istreambuf_迭代器 问题:

为什么没有任何iostream\u迭代器、streambuf\u迭代器、string\u迭代器std::string::iterator和std::string::const\u迭代器或stringbuf\u迭代器

为什么上面列出的4个迭代器没有像std::vector::const_迭代器这样的常量版本

如果这些野兽没有提供开始和结束方法,我们应该如何迭代它们?上述4个迭代器的用途是什么

N00b问题:我在哪里可以找到一个好的参考资料,详细说明这些类背后的逻辑,以及一些关于如何使用它们的好例子

希望有经验的人能为上述问题提供一个很好的答案

附注:现实生活情况:

void writeToStream(std::ostream &out);
int main ()
{
    std::ostringstream byteStream;
    writeToStream(byteStream);
    std::string byteString = byteStream.str();

    for (unsigned short i = 0; i < byteString.size(); ++i)
    {
        //do something with each byteString[i]
    }
    return 0;
}

我的猜测是,我可以使用ostream并通过使用迭代器对其元素进行迭代,就像std::vector一样,而不是使用ostringstream和str方法将其转换为字符串,但是我找不到任何与此相关的信息。

这些流迭代器的存在是为了使用标准算法直接从容器向流写入/读取数据。因此,与其写作

for (vector<int>::iterator i=v.begin(); i!=v.end(); ++i)
    cout << *i <<"\n";

如需参考,请勾选,或。我认为这是一个很好的技巧,但实际上没有多大帮助,因为您对输入/输出几乎没有控制权。

这些流迭代器可以使用标准算法直接从容器向流写入或读取数据。因此,与其写作

for (vector<int>::iterator i=v.begin(); i!=v.end(); ++i)
    cout << *i <<"\n";
如需参考,请勾选,或。我认为这是一个巧妙的技巧,但实际上没有多大帮助,因为您对输入/输出几乎没有控制权

为什么没有任何iostream\u迭代器、streambuf\u迭代器 stringbuf_迭代器

我不知道。虽然我猜这只是因为它们会更复杂,而且没有足够的需求

为什么上面列出的4个迭代器没有像这样的常量版本 std::vector::const_迭代器

常量输入迭代器是相当冗余的,您只能从中读取,而不能写入。常量输出迭代器将毫无意义,因为这将破坏它的唯一用途,即输出

如果这些野兽没有,我们应该如何迭代它们 提供开始和结束方法?这项研究的目的是什么 4个以上的迭代器

通过使用各自的构造函数创建迭代器,例如

std::istream_iterator<int> in_begin(std::cin), in_end;
std::ostream_iterator<int> out_begin(std::cout, "\n");
std::copy(in_begin, in_end, out_begin);
请注意,istream_迭代器的end迭代器是通过不向其构造函数传递任何参数创建的,并且输出迭代器没有等效的end迭代器

为什么没有任何iostream\u迭代器、streambuf\u迭代器 stringbuf_迭代器

我不知道。虽然我猜这只是因为它们会更复杂,而且没有足够的需求

为什么上面列出的4个迭代器没有像这样的常量版本 std::vector::const_迭代器

常量输入迭代器是相当冗余的,您只能从中读取,而不能写入。常量输出迭代器将毫无意义,因为这将破坏它的唯一用途,即输出

如果这些野兽没有,我们应该如何迭代它们 提供开始和结束方法?这项研究的目的是什么 4个以上的迭代器

通过使用各自的构造函数创建迭代器,例如

std::istream_iterator<int> in_begin(std::cin), in_end;
std::ostream_iterator<int> out_begin(std::cout, "\n");
std::copy(in_begin, in_end, out_begin);
请注意,istream_迭代器的end迭代器是通过不向其构造函数传递任何参数创建的,并且输出迭代器没有等效的end迭代器

为什么没有: *iostream_迭代器 *streambuf_迭代器

不知道。可能是因为在进行输入和输出时很难定义语义。当您使用迭代器在流中前进然后后退时,您希望发生什么

字符串迭代器 stringbuf_迭代器? 现有迭代器很容易涵盖这些内容:

std::string                  line; // load line.
std::stringstream            linestream(line);
std::istream_iterator<int>   lineIterator(linestream);
为什么上面列出的4个迭代器没有像std::vector::const_迭代器这样的常量版本

因为当你迭代一个流时,流的状态正在改变

如果这些野兽没有提供开始和结束方法,我们应该如何迭代它们?上述4个迭代器的用途是什么

因为河流通常是一个方向。您不会从头开始迭代,而是从流中的当前位置迭代到最后。因此,您只需声明一个迭代器来指定流。迭代器从当前位置和mov开始 快结束了。您可以通过不指定流来声明流结束迭代器

 std::istream_iterator<int>   loop(std::cin);
 for(;loop != std::istream_iterator<int>(); ++loop)
 {
     std::cout << *loop;
 }
N00b问题:我在哪里可以找到一个好的参考资料,详细说明这些类背后的逻辑,以及一些关于如何使用它们的好例子

这里是个好地方。 搜索C++ iStReMax迭代器,你会得到很多点击。 希望有经验的人能为上述问题提供一个很好的答案

希望如此

为什么没有: *iostream_迭代器 *streambuf_迭代器

不知道。可能是因为在进行输入和输出时很难定义语义。当您使用迭代器在流中前进然后后退时,您希望发生什么

字符串迭代器 stringbuf_迭代器? 现有迭代器很容易涵盖这些内容:

std::string                  line; // load line.
std::stringstream            linestream(line);
std::istream_iterator<int>   lineIterator(linestream);
为什么上面列出的4个迭代器没有像std::vector::const_迭代器这样的常量版本

因为当你迭代一个流时,流的状态正在改变

如果这些野兽没有提供开始和结束方法,我们应该如何迭代它们?上述4个迭代器的用途是什么

因为河流通常是一个方向。您不会从头开始迭代,而是从流中的当前位置迭代到最后。因此,您只需声明一个迭代器来指定流。迭代器从当前位置开始并向末尾移动。您可以通过不指定流来声明流结束迭代器

 std::istream_iterator<int>   loop(std::cin);
 for(;loop != std::istream_iterator<int>(); ++loop)
 {
     std::cout << *loop;
 }
N00b问题:我在哪里可以找到一个好的参考资料,详细说明这些类背后的逻辑,以及一些关于如何使用它们的好例子

这里是个好地方。 搜索C++ iStReMax迭代器,你会得到很多点击。 希望有经验的人能为上述问题提供一个很好的答案



希望如此。

请记住,流是流,而不是容器,这意味着在大多数情况下,您无法返回和/或将销毁您所保存的数据read@PasmaHH:好的,这是一个很好的观点。谢谢不过,我还是希望对这些问题有一个详细的解释。你为什么把字符串放在这里?有string::iterator、string::const_iterator和string::begin和string::end。@BenjaminLindley Oups。。。我的错。你说得对。请记住,流是流,而不是容器,这意味着在大多数情况下,你无法返回和/或将破坏你所保存的数据read@PasmaHH:好的,这是一个很好的观点。谢谢不过,我还是希望对这些问题有一个详细的解释。你为什么把字符串放在这里?有string::iterator、string::const_iterator和string::begin和string::end。@BenjaminLindley Oups。。。我的错。你说得对。什么是TC++PL?汤普金斯县公共图书馆?对不起,忘了链接了。这是斯特罗斯托普的书。谢谢对于漂亮的Apache文档,+1。什么是TC++PL?汤普金斯县公共图书馆?对不起,忘了链接了。这是斯特罗斯托普的书。谢谢对于尼斯Apache文档,+1。迭代器是输入/输出限定的,因为您可以将它们用作源或目标,而不是同时用作源或目标,因为假定它们使用或生成一个流,而您不能返回到以前的位置。感谢std::copy使用示例,Benjamin。您的评论非常有用,但我决定接受Loki的回答,因为它包含更多的细节。迭代器是输入/输出限定的,因为您可以将它们用作源或目标,而不是两者,假设他们消费或生成了一个流,您不能回到以前的位置。你的评论非常有用,但我决定接受洛基的回答,因为它包含了更多的细节。好吧,谢谢你的好回答,谢谢你花时间提供它。在您的示例代码中,为什么要将循环与std::istream_迭代器进行比较?因为:std::istream_迭代器是一个迭代器,它将流的结束标记为容器上的结束。当递增循环超过流的末尾时,它将与这样创建的对象进行比较。确定,有意义。再次感谢!好的,谢谢你的回答,谢谢你花时间提供。在您的示例代码中,为什么要将循环与std::istream_迭代器进行比较?因为:std::istream_迭代器是一个迭代器,它将流的结束标记为容器上的结束。当递增循环超过流的末尾时,它将与这样创建的对象进行比较。确定,有意义。再次感谢!