2

我正在尝试使用迭代器初始化字符串,类似这样的工作:

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);

谢谢你。

4

4 回答 4

2

我不认为您可以将结束迭代器推进到合适的位置:推进迭代器意味着读取输入,而且两个迭代器都引用同一个流 - 因此推进一个迭代器意味着推进第二个。它们最终都引用了流中的相同位置。

除非您愿意编写或找到对某个迭代器引用的 n 个项目执行操作的迭代器适配器(boost?),否则可能无法像这样初始化字符串。或者您使用其他方法读取值并稍后设置字符串的值。

于 2009-11-09T19:20:12.453 回答
1

istream_iterator 是输入,所以你的第二个代码片段不正确,你不能这样做(第二遍)。请看这里并注意“单通道”算法支持(“描述”标题下的第二段)。第一个片段不会尝试执行 2 遍。

这个解释可以吗?BTW SGI STL 参考(从我发布链接的地方)有些过时,但对于一些快速参考非常有用(我认为)。我建议将其添加为书签。

于 2009-11-09T19:32:06.823 回答
1

istream_iterator 是一个非常有限的迭代器,称为输入迭代器。

见:http ://www.sgi.com/tech/stl/InputIterator.html

但基本上对于输入迭代器,很少有保证。
具体到您的情况:

i == j 并不意味着 ++i == ++j。

所以你的第一个例子是一个迭代器,它被传递到流的末尾。它是有效的(只要它不递增)并且与其他迭代器相当,因此适用于读取整个流。

于 2009-11-09T19:33:12.957 回答
0

根据标准 [24.5.1]/1:

[...] 没有参数的构造函数 istream_iterator() 总是构造一个流输入迭代器对象的结尾,这是唯一用于结束条件的合法迭代器。[...] istream 迭代器的主要特点是 ++ 运算符不保持相等性,也就是说,i == j 根本不保证 ++i == ++j。每次使用 ++ 时都会读取一个新值。

[24.5.1]/3

两个流尾迭代器总是相等的。流结束迭代器不等于非流结束迭代器。当从同一个流构造时,两个非流结束迭代器是相等的

第一段指出,除了流结束迭代器之外,您不能使用任何其他迭代器作为结束条件,因此您的第一次使用是正确且符合预期的。本章的第三段指出,任何两个进入同一流的非流结束迭代器都保证在任何时候都是相等的。也就是说,从语言的角度来看,第二种用法是正确的,并且会提供您得到的结果。

第 1 段的最后一部分,其中指出i == j并不暗示++i == ++j处理流中存在的最后一个元素的特定情况。在递增第一个迭代器(或ij)后,该迭代器使用数据。推进另一个迭代器将到达流的末尾,因此两个迭代器将不同。在所有其他情况下(流中还剩下一个以上的数据)++i == ++j,。

另请注意,该句子++i == ++j对同一元素(流)执行两个变异操作,因此两个迭代器中的哪一个获取流中的第一个/第二个数据不是。

于 2009-11-09T19:37:33.583 回答