C++流混淆:istreambuf_iterator vs istream_iterator?

dex*_*rey 43 c++ istream streambuf

istreambuf_iterator和之间有什么区别istream_iterator?一般来说,stream和streambufs有什么区别?我真的找不到任何明确的解释,所以决定在这里问.

Xeo*_*Xeo 46

IOstreams使用streambufs作为输入/输出的源/目标.实际上,streambuf系列完成了有关IO的所有工作,IOstream-family仅用于格式化和字符串/字符串转换.

现在,istream_iterator采用一个模板参数,说明streambuf中未格式化的字符串序列应该被格式化为什么,就像istream_iterator<int>将所有传入的文本解释为(以空格分隔)为ints一样.

另一方面,istreambuf_iterator只关心原始字符并直接迭代istream它传递的相关streambuf .

通常,如果您只对原始字符感兴趣,请使用istreambuf_iterator.如果您对格式化输入感兴趣,请使用istream_iterator.

我所说的所有内容也适用于ostream_iteratorostreambuf_iterator.

  • 只是一个小细节:iostream家族实际上并没有做太多格式化工作-大部分委托给了与流相关的语言环境。iostream基本上是一个“匹配器”,将语言环境与streambuf放在一起。不过,大多数实际工作都委托给一个或另一个。 (2认同)

Jer*_*fin 14

这是一个非常严密的秘密:本身就是一个iostream ,几乎与从计算机上的文件读取或写入文件无关.

iostream基本上充当streambuf和locale之间的"媒人":

在此输入图像描述

iostream存储了一些关于如何进行转换的状态(例如,转换的当前宽度和精度).它使用那些来指示语言环境如何以及在何处进行转换(例如,将此数字转换为缓冲区中宽度为8且精度为5的字符串).

虽然你没有直接询问它,但是反过来的语言环境实际上只是一个容器 - 但是(相当奇怪)一个类型安全的异构容器.它包含的东西是facets.构面对象定义整个区域设置的单个构面.该标准定义了从读取和写入数字(num_get,num_put)到分类字符(ctype facet)的所有方面.

默认情况下,流将使用"C"语言环境.这是非常基本的 - 数字只是转换为数字流,它识别为字母的唯一内容是26个小写字母和26个大写英文字母,依此类推.但是,您可以imbue选择具有不同区域设置的流.您可以选择要在字符串中指定的名称使用的语言环境.一个特别有趣的是由空字符串选择的一个.使用空字符串基本上告诉运行时库选择它"认为"最合适的语言环境,通常基于用户配置操作系统的方式.这允许代码以本地化格式处理数据,而无需针对任何特定语言环境明确编写.

因此,a istream_iterator和an 之间的基本区别在于istreambuf_iterator来自istreambuf_iterator的数据没有经过(大部分)由语言环境完成的转换,但是来自a的数据istream_iterator已经被语言环境转换.

对于它的价值,认为"大部分的"在上一段中所指的事实,当你从一个istreambuf读取数据(通过迭代器或其他方式)基于地区的转型之一点点做:随着各种"格式化"种类的东西,语言环境包含一个codecvt facet,这是用来从一些外部表示转换为一些内部表示(例如,UTF-8到UTF-32).

忽略这样一个事实可能更有意义,即它们都存储在一个语言环境中,并且只考虑所涉及的各个方面:

在此输入图像描述

这就是a istream_iterator和a之间的真正区别istreambuf_iterator.对来自任何一个数据的数据进行一点转换(至少可能),但对来自数据的数据进行的转换要少得多istreambuf_iterator.