При работе с потоками данных я предпочитаю писать код в терминах шаблонов и итераторов. Часто мне нужно «заглянуть» на следующего персонажа. Чтобы код мог работать с двунаправленными итераторами, у меня есть фрагмент, который выглядит следующим образом:
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
Другими словами, увеличение одной копии итератора приводит к увеличению всех из них!
Я понимаю, что итераторы файлового потока имеют ограничения в том, что они могут работать только с тем, что в данный момент находится в буфере чтения, связанном с файлом. Так что не может быть решения, которое точно соответствует тому, что я хочу. Есть ли способ сделать то, что я хочу?