istreambuf_iterator
和istream_iterator
之间有什么区别?
一般来说,stream和streambufs有什么区别?
我真的找不到任何明确的解释,所以决定在这里问。
答案 0 :(得分:42)
IOstreams使用streambufs作为输入/输出的源/目标。实际上,streambuf系列完成了有关IO的所有工作,IOstream-family仅用于格式化和字符串/字符串转换。
现在,istream_iterator
接受一个模板参数,该参数说明streambuf中未格式化的字符串序列应格式化为什么,如istream_iterator<int>
将所有传入文本解释为(空格分隔)为{{1 }}第
另一方面,istreambuf_iterator
只关心原始字符,并直接遍历它传递的int
的关联streambuf。
通常,如果您只对原始字符感兴趣,请使用istream
。如果您对格式化输入感兴趣,请使用istreambuf_iterator
。
我所说的所有内容也适用于ostream_iterator
和ostreambuf_iterator
。
答案 1 :(得分:11)
这是一个非常严密的秘密:iostream 本身,几乎与从您计算机上的文件读取或写入文件无关。
iostream基本上充当了&#34;媒人&#34;在streambuf和locale之间:
iostream存储了一些关于如何进行转换的状态(例如,转换的当前宽度和精度)。它使用那些来指导语言环境如何以及在何处进行转换(例如,将此数字转换为缓冲区中宽度为8且精度为5的字符串。)
虽然你没有直接询问它,但是反过来的语言环境实际上只是一个容器 - 但是(相当奇怪)一个类型安全的异构容器。它包含的内容是facet
。构面对象定义整个区域设置的单个构面。该标准定义了从读取和写入数字(num_get
,num_put
)到分类字符(ctype facet)的所有方面。
默认情况下,流将使用&#34; C&#34;语言环境。这是非常基本的 - 数字只是转换为数字流,它识别为字母的唯一内容是26个小写字母和26个大写英文字母,依此类推。但是,您可以imbue
使用您选择的不同区域设置的流。您可以选择要在字符串中指定的名称使用的语言环境。一个特别有趣的是由空字符串选择的那个。使用空字符串基本上告诉运行时库选择它所认为的语言环境&#34;是最合适的,通常基于用户配置操作系统的方式。这允许代码以本地化格式处理数据,而无需为任何特定语言环境明确编写。
因此,istream_iterator
和istreambuf_iterator
之间的基本区别是来自istreambuf_iterator的数据没有经过(大部分)由语言环境完成的转换,但是来自istream_iterator
的数据已被区域设置转换。
它的价值在哪,&#34;大多数&#34;在上一段中提到的事实是,当您从istreambuf(通过迭代器或其他方式)读取数据时,一小部分基于语言环境的转换 完成:以及各种&#34;格式化& #34;各种各样的东西,locale包含一个codecvt facet,这是用于从一些外部表示转换为某种内部表示(例如,UTF-8到UTF-32)的东西。
忽略这样一个事实可能更有意义,即他们都存储在一个语言环境中,并且只考虑所涉及的各个方面:
这是istream_iterator
和istreambuf_iterator
之间的真正区别。对任何一个数据进行了一些转换(至少可能)(但至少可能),但对来自istreambuf_iterator
的数据进行了大量 less 。