【问题标题】:istreambuf_iterator with structs带有结构的 istreambuf_iterator
【发布时间】:2015-12-01 07:12:42
【问题描述】:

我很难让 istreambuf_iterator 与除 char 之外的其他类型一起工作。我们都知道您可以将流转换为这样的范围:

istreambuf_iterator<char>(ifstream("some_file")) //now we have an iterator that reads chars each step.

我有一个结构的二进制流,而不是字符。所以我需要能够做到这一点:

istreambuf_iterator<MyStruct>(ifstream("some_file"))

我想轻松地遍历流中的所有 MyStruct。这我无法开始工作,因为 ifstream 是一个 istream,它是一个 basic_istream&lt;char&gt;,它只适用于 istreambuf_iterator&lt;char&gt;,而不是 istreambuf_iterator&lt;MyStruct&gt;

我已经编写了自己的迭代器,但我想使用 STD 迭代器,因为它看起来很完美。他们为什么要做这样的事情?为什么我不能使用 istreambuf_iterator 迭代 ifstream 中的结构?

编辑:

人们建议将 istream_iterator 与 operator>> 的自定义实现一起使用。这将起作用,但对于我的特定用途,我需要阅读特定数量的 MyStruct,直到 EOF。该流包含 5 个 MyStruct,然后包含更多不应该作为 MyStruct 读取的数据。所以我需要通过像这样偏移“开始迭代器”来为范围创建“结束迭代器”:

auto begin = istream_iterator<MyStruct>(the_istream);
auto end = istream_iterator<MyStruct>(the_istream) + 5;

但是这个我不知道有没有可能。

拥有一个具有所有这些功能的完全标准的 STL 迭代器会很好,而且如果标准迭代器经过深思熟虑,它们似乎很容易涵盖所有这些用例。我想最短和最简单的解决方案是继续使用我的自定义迭代器。

【问题讨论】:

  • 你为什么不使用istream_iterator
  • 因为没有为 MyStruct 定义运算符>>。也许重载 + istream_iterator 是我能得到的最接近的?任何自动获取如何读取 MyStruct 的 binary_istream_iterator?
  • 你为什么不做一个istream&amp; operator&gt;&gt;(istream&amp;, MyStruct&amp;)?这就是你应该做的。

标签: c++ iterator


【解决方案1】:

ifstreambasic_ifstream&lt;char&gt; 的类型定义。由于您使用的流的类型好像包含chars,因此您只能迭代chars 也就不足为奇了。你可能会想试试这个(我做过):

istreambuf_iterator<MyStruct>(basic_ifstream<MyStruct>("some_file"))

但它不起作用,因为它需要为MyStruct 提供一个char_traits 类,而char_traits 又需要定义一个int_type,在这种情况下它是一个包含MyStruct 的整数。大概MyStruct 不能以任何整数类型存储,所以我们运气不好。

我假设你已经知道你可以重载operator&gt;&gt;(istream&amp;, MyStruct&amp;)....

【讨论】:

  • 我的意思是,我已经实现了一个迭代器,它是从 std::istream (即 basic_stream)构造的,但它包含 MyStruct 的。使用这个迭代器,我可以使用基于 for 的 C++11 范围循环遍历所有 MyStruct,同时从流中动态读取它们。但我想改用 istreambuf_iterator 。他们可以很容易地制作一个像我一样的迭代器,但他们选择了一些不可用的变体。我不知道如何使用它。
  • @user1284878:那你的问题是什么?是“为什么 C++ 标准的人很愚蠢?”
  • 几乎是的。我的意思是,如果 istreambuf_iterator 只需要一个 istream,他们就可以轻松地让 istreambuf_iterator 变得更有用。在我的迭代器中,我只是 istream.read((char *) &myStruct, sizeof(MyStruct)) 并在迭代器被取消引用时返回它。 istreambuf_iterator 也可以这样做。
  • 你知道任何像我一样的 Boost 迭代器,或任何 C++17 改进吗?当 C++ 类似于 99% 的迭代器模板时,我不喜欢添加自定义迭代器。
  • @user1284878:不要因为添加自定义迭代器而感到难过——它们非常有用。整个 STL 实际上是在邀请您编写自己的迭代器,尽管实际上很少有人这样做。多年前受教对我来说是一个启示。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-04
  • 1970-01-01
  • 2019-06-03
  • 2015-03-29
  • 1970-01-01
  • 1970-01-01
  • 2020-09-01
相关资源
最近更新 更多