std :: istreambuf_iterator“peek”with std :: ifstream
在处理数据流时,我更愿意使用模板和迭代器编写代码。我经常需要“偷看”下一个角色。为了使代码能够处理无双向迭代器,我有一个片段,看起来像这样:std :: istreambuf_iterator“peek”with std :: ifstream
template <class I>
I next(I it) {
return ++it;
}
显然,这使得迭代器的副本,增量拷贝并返回它。这倾向于非常好地工作...除非std::istreambuf_iterator
在std::ifstream
上运行。例如,给定一个文件 “test.txt
” 有内容 “ABCD
”,和下面的代码:
#include <fstream>
#include <iostream>
template <class I>
I next(I it) {
return ++it;
}
int main() {
std::ifstream file("test.txt", std::ios::binary);
std::istreambuf_iterator<char> it(file);
std::cout << *next(it) << std::endl;
std::cout << *it << std::endl;
}
输出是:
$ ./test
B
B
取而代之的是我希望的:
$ ./test
B
A
换句话说,递增迭代器的一个副本,具有增加所有的净效应!
我意识到文件流迭代器的局限性在于它们只能操作与文件关联的读缓冲区中的当前内容。所以可能没有一个解决方案与我想要的完全匹配。有没有办法做我想要的?
那么,它实际上并没有增加所有迭代器,而是消耗流,它最终具有相同的效果。如果您想要提前浏览,您需要在流本身AFAIK上执行此操作。
您在帖子的标题中提到了'偷看'。 std :: istream有一个peek()
方法。 使用它。
但我想使用迭代器,理想情况下代码将能够使用指针或'std :: istreambuf_iterator'或任何像迭代器一样工作的东西。 – 2011-06-13 01:40:00
流缓冲区迭代器是一次迭代器。你不能倒退,它不具有双向功能,如vector::iterator
和string::iterator
等等。没有办法创建独立于任何其他迭代器实例的独立文件流迭代器副本。这是不可能的,因为流迭代器无论是否被复制,都始终在同一个流对象上工作。复制迭代器不会复制文件流。
是的,我想通了。这就是为什么我说“净效应”。我认为这个角色是通过增加“消耗”的,我只是希望有一些聪明的东西可以做我想做的事情。 – 2011-06-13 01:43:05
你需要明确地“寻找”它,无论如何,他都不会这么做。 – 2011-06-13 02:37:31