在 C++11 中累积从文件中读取数据的整数
Posted
技术标签:
【中文标题】在 C++11 中累积从文件中读取数据的整数【英文标题】:Accumulate integers reading data from file in C++11 【发布时间】:2017-08-03 09:29:37 【问题描述】:我想问一下accumulate
从文件中读取整数时的工作原理。
通常accumulate
采用指向容器第一个位置的迭代器和指向同一容器最后位置的迭代器(例如vector
)和初始值。
如果我们需要从文件中读取数据,则编写以下代码
ifstream dataFile("ints.dat");
accumulate(istream_iterator<int>(dataFile), istream_iterator<int>(), 0);
创建的时间迭代器不是同一个容器的迭代器。我无法理解这是如何正常工作的并且不会导致无限循环。
accumulate
的可能实现如下:
template<class InputIt, class T>
T accumulate(InputIt first, InputIt last, T init)
for (; first != last; ++first)
init = init + *first;
return init;
【问题讨论】:
因为你在这里处理的不是容器,而是一个特殊的类,它有自己的重载函数,使其像迭代器一样工作,并且识别特殊的“结束”对象? 【参考方案1】:这里没有涉及容器,因为您使用的是具有特定行为的流迭代器。
当您增加istream_iterator
时,将从基础流中读取一个值。如果读取时发生错误(fail()
返回true
),则迭代器将成为流结束迭代器。
默认构造的 istream_iterator
始终是一个 end-of-stream 迭代器,因此只有当 istream_iterator
上的增量运算符无法读取下一个值时,两个迭代器才会比较等于(在文件末尾,或发生错误时)。
标准中的一些相关引用:
[istream.iterator-1]
构造之后,每次
++
是 使用时,迭代器读取并存储值T
。如果迭代器无法读取和存储T
的值(fail()
on 流返回 true),迭代器变得等于 流结束迭代器值。 不带参数的构造函数istream_iterator()
总是构造一个 end-of-stream 输入迭代器对象,即 用于结束条件的唯一合法迭代器。 [...][istream.iterator-2]
两个流尾迭代器总是相等的。流结束迭代器不等于非流结束迭代器。 [...]
【讨论】:
【参考方案2】:这就是 C++ 的美妙之处 :-)
要完全理解这一点,我们必须了解 type 和 object 之间的区别,并且符号 (++
,!=
) 只是函数 (虽然特别定义)。
标准算法accumulate
定义为:
-
获取容器开头的
iterator
,
以iterator
象征容器的末端,
取初始值
在所示的实现中,expalin 的关键部分是:
first != last
.
这不是一个很复杂的表达式。但是幕后发生的事情非常有趣。
我们可以看到类型是istream_iterator<int>
。这种类型定义了许多操作。其中一个操作是操作++
(加号 -或- 增量 -或- 移动到下一个位置)。这很容易解释:++
的调用就像为迭代器 type 定义了一个函数 move_to_next()
。然后当使用++
时,就像为声明的object 调用函数move_to_next()
。
以同样的方式定义了一个特殊的函数!=
(感叹号等于-或-不等于)。
为了这个解释,让我们重新定义它bool compare_iterators_not_equal(istream_iterator<int> lhs, istream_iterator<int> rhs)
。该函数将两个 istream_iterator 对象作为其参数,并评估这两个对象是否不相等。
现在要结合这些信息...
结束迭代器对象不必是容器中的物理位置。它只需要符号化容器的结尾,这样当比较迭代器对象时(通过compare_iterators_not_equal
函数(!=
)),它将返回迭代器已到达结尾。
所以第一个迭代器是在输入流上定义的,并继续读取下一个数据。当它到达输入的末尾时,迭代器将其状态更改为表示它已到达输入末尾的状态。当此状态下的迭代器与默认构造的迭代器(象征输入结束)进行比较时,比较函数知道:它是输入结束。然后循环结束。
【讨论】:
以上是关于在 C++11 中累积从文件中读取数据的整数的主要内容,如果未能解决你的问题,请参考以下文章
在 C++ 中写入整数并从二进制文件中读取它们:字节数 mismaych