我正在尝试使用迭代器初始化字符串,这样的工作原理:
ifstream fin("tmp.txt");
istream_iterator<char> in_i(fin), eos;
//here eos is 1 over the end
string s(in_i, eos);
但这不是:
ifstream fin("tmp.txt");
istream_iterator<char> in_i(fin), eos(fin);
/* here eos is at this same position as in_i*/
//moving eos forward
for (int i = 0; i < 20; ++i)
{
++eos;
}
// trying to initialize string with
// pair of iterators gives me ""
// result
string s(in_i, eos);
谢谢。
答案 0 :(得分:2)
我认为你不能将最终迭代器推进到合适的位置:推进迭代器意味着读取输入,两个迭代器都引用相同的流 - 因此推进一个迭代器意味着推进第二个迭代器。它们最终都引用了流中的相同位置。
除非您愿意编写或找到对某些迭代器引用的n个项执行操作的迭代器适配器(boost?),否则可能无法像这样初始化字符串。或者您使用其他方法读取值并稍后设置字符串的值。
答案 1 :(得分:1)
istream_iterator,因此你的第二个代码片段不正确,你不能这样做(第二遍)。请查看here并注意“单通”算法支持(“描述”标题下的第二段)。第一个片段不会尝试执行2次传递。
这个解释好吗? BTW SGI STL参考(从我发布的链接)有点过时但非常适用于一些快速参考(根据我的观点)。我建议将它加入书签。
答案 2 :(得分:1)
istream_iterator是一个非常有限的迭代器,它被称为输入迭代器。
请参阅:http://www.sgi.com/tech/stl/InputIterator.html
但基本上对于输入迭代器来说,很少有保证 特别针对您的情况:
i == j并不意味着++ i == ++ j。
所以你的第一个例子是一个传递给流结束的迭代器。它是有效的(只要它不增加)并且与其他迭代器相当,因此可用于读取整个流。
答案 3 :(得分:0)
来自标准[24.5.1] / 1:
[...]没有参数的构造函数 istream_iterator()总是构造 流输入迭代器的结尾 对象,这是唯一合法的 迭代器用于结束 条件。 [...] istream迭代器的主要特点是++运算符不保持相等,即i == j根本不保证++ i == ++ j。每次使用++时,都会读取一个新值。
[24.5.1] / 3
两个流末端迭代器 永远相等。流末尾 迭代器不等于a 非结束流迭代器。二 非结束流迭代器是相等的 当他们从建造 相同的流
第一段声明您不能使用任何流末端迭代器作为结束条件,因此您的第一次使用是正确的和预期的。本章的第三段规定,保证在同一个流中的任何两个非流末端迭代器始终相等。也就是说,从语言的角度来看,第二种用法是正确的,并且会提供你得到的结果。
第1段的最后一部分,其中指出i == j
并不暗示++i == ++j
处理流中最后一个元素的特定情况。递增第一个迭代器(i
或j
)后,该迭代器将使用该数据。推进另一个迭代器将到达流的末尾,因此两个迭代器将不同。在所有其他情况下(流中还有多个数据),++i == ++j
。
另请注意,句子++i == ++j
对同一元素(流)执行两次变异操作,因此两个迭代器中的哪一个不能获取流中的第一个/第二个数据。