2

我想有人不得不问这些问题,所以请多多包涵。

让我们考虑以下野兽:

  • ostream
  • istream
  • iostream
  • 流缓冲
  • 字符串- 根据本杰明的观察,这个不属于这里。
  • 字符串缓冲区

和以下迭代器:

  • ostream_iterator
  • ostreambuf_iterator
  • istream_iterator
  • istreambuf_iterator

问题:

为什么不存在iostream_iterator, streambuf_iterator, string_iterator(std::string::iterator 和 std::string::const_iterator 确实存在) 或stringbuf_iterator

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

如果它们不提供 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通过使用类似 for 的迭代器来使用和迭代其元素std::vector,而不是使用ostringstreamandstr()将其转换为 a 的方法string,但我找不到任何有关此的信息。

4

3 回答 3

4

为什么没有:
* iostream_iterator
* streambuf_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”你会得到很多点击。

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

希望。

于 2012-08-09T21:50:39.343 回答
3

为什么没有 iostream_iterator、streambuf_iterator 或 stringbuf_iterator?

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

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

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

如果它们不提供 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);

请注意,结束迭代器 foristream_iterator是通过简单地不向其构造函数传递任何参数来创建的,并且没有等效于end()输出迭代器的 for 。

于 2012-08-09T21:46:43.443 回答
1

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

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"));

如需参考,请检查类似thisTC++PL的内容。恕我直言,它们是一个巧妙的技巧,但并没有太大帮助,因为您几乎无法控制输入/输出。

于 2012-08-09T21:39:08.640 回答