Streambuf、Ostream、Ostreambuf、iStream、ISTREAMBUF 和相关迭代器



我想有人必须问这些问题,所以请耐心等待。

让我们考虑以下野兽:

  • ostream
  • 艾瑞
  • 艾欧流
  • 流布夫
  • 字符串 - 根据本杰明的观察,这个不属于这里。
  • 弦布夫

以及以下迭代器:

  • ostream_iterator
  • ostreambuf_iterator
  • istream_iterator
  • istreambuf_iterator

问题:

为什么没有任何iostream_iteratorstreambuf_iterator string_iterator (std::string::itrator 和 std::string::const_iterator 确实存在)或stringbuf_iterator

为什么上面列出的 4 个迭代器没有像 std::vector<T>::const_iterator 这样的 const 版本?

如果这些野兽不提供 begin() 和 end() 方法,我们应该如何迭代它们中的任何一个?以上 4 个迭代器的目的是什么?

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

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


PS:真实生活情况:

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一样,而不是使用 ostringstreamstr() 方法将其转换为string,但我找不到任何有关这方面的信息。

为什么没有:
* iostream_iterator
* streambuf_iterator

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

  • string_iterator
  • stringbuf_iterator?

这些很容易被现有的迭代器覆盖:

std::string                  line; // load line.
std::stringstream            linestream(line);
std::istream_iterator<int>   lineIterator(linestream);

为什么上面列出的 4 个迭代器没有像 std::vector::const_iterator 这样的 const 版本?

因为当您遍历流时,流的状态正在发生变化。

如果这些野兽不提供 begin() 和 end() 方法,我们应该如何迭代它们中的任何一个?以上 4 个迭代器的目的是什么?

因为流通常是单向的。您不是从头开始迭代,而是从流中的当前位置迭代到结束。因此,您只需声明一个指定流的迭代器。迭代器从当前位置开始,然后向末尾移动。您可以通过不对流进行切割来声明流迭代器的结束。

 std::istream_iterator<int>   loop(std::cin);
 for(;loop != std::istream_iterator<int>(); ++loop)
 {
     std::cout << *loop;
 }

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

这是一个好地方。
搜索"C++ istream_iterator"你会得到很多点击。

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

希望。

为什么没有任何iostream_iterator,streambuf_iterator或 stringbuf_iterator?

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

为什么上面列出的 4 个迭代器没有像 const 这样的 const 版本 std::vector<T>::const_iterator

常量输入迭代器是相当多余的,无论如何你只能从它们读取,而不能写入它们。 常量输出迭代器将毫无意义,因为这会破坏它的唯一目的,即输出。

如果这些野兽不这样做,我们应该如何迭代它们中的任何一个 提供 begin() 和 end() 方法?的目的是什么 超过 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_iterator 的结束迭代器是通过简单地向其构造函数传递任何参数来创建的,并且输出迭代器没有等效的end()

这些流迭代器的存在是为了使用标准算法直接从容器写入/读取流。所以不是写

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

你可以只使用 std::copy:

copy(v.begin(), v.end(), ostream_iterator(cout, "n"));

作为参考,请检查类似这样的东西,或TC++PL。 恕我直言,它们是一个巧妙的技巧,但并没有多大帮助,因为您对输入/输出几乎没有控制权。

最新更新