Итерация потоков в обратном порядке

Я хотел бы использовать std::find_if пройти через содержимое std::streambuf задом наперед. Это включает в себя создание std::reverse_iterator из std::istream_iterator или же std::istreambuf_iterator, К сожалению, попытка сделать это, как показано в примере кода ниже, приводит к ошибке компиляции. Как я могу заставить это работать? При необходимости решения с использованием Boost были бы отличными.

#include <cstddef>
#include <fstream>
#include <iterator>

template <class Iterator>
static std::reverse_iterator<Iterator>
make_reverse_iterator(Iterator i)
{
return std::reverse_iterator<Iterator>(i);
}

int main()
{
std::ifstream is{"foo.txt", std::ios::binary};
std::istreambuf_iterator<char> i{is};
auto r = make_reverse_iterator(i);
// Error =(
*r;
return EXIT_SUCCESS;
}

Вот ошибка компиляции, сообщенная g++-4.8.1:

In file included from /opt/local/include/gcc48/c++/bits/stl_algobase.h:67:0,
from /opt/local/include/gcc48/c++/bits/char_traits.h:39,
from /opt/local/include/gcc48/c++/ios:40,
from /opt/local/include/gcc48/c++/istream:38,
from /opt/local/include/gcc48/c++/fstream:38,
from ri.cpp:9:
/opt/local/include/gcc48/c++/bits/stl_iterator.h: In instantiation of 'std::reverse_iterator<_Iterator>::reference std::reverse_iterator<_Iterator>::operator*() const [with _Iterator = std::istream_iterator<char>; std::reverse_iterator<_Iterator>::reference = const char&]':
ri.cpp:24:3:   required from here
/opt/local/include/gcc48/c++/bits/stl_iterator.h:163:10: error: no match for 'operator--' (operand type is 'std::istream_iterator<char>')
return *--__tmp;
^

Спасибо за вашу помощь!

1

Решение

Насколько я знаю, входные итераторы (например, из ifstreams) не способны вернуться назад, поэтому обратный итератор недоступен. Это имеет смысл, потому что, если вы подумаете об этом, пересылка reverse_iterator (то есть operator ++) является обратной стороной нормального итератора (то есть operator -), и поэтому, если обычный итератор не предоставляет operator -, тогда он Естественно, что reverse_iterator не должен существовать.

Насколько я помню, существует 3 типа итераторов: прямой, двунаправленный и произвольный доступ. Вперед может идти только в одном направлении (угадайте, в каком: P), двунаправленный может идти вперед и назад на 1, а произвольный доступ может идти вперед и назад с любым приращением.

Как видите, итераторы с произвольным доступом предлагают все операции двунаправленных итераторов (и более), которые сами предлагают все операции итераторов прямого преобразования (и более). Это означает, что итераторы произвольного доступа могут использоваться там, где требуются прямые итераторы, но не наоборот.

Как вы, возможно, догадались из этого объяснения, для make_reverse_iterator, скорее всего, требуются итераторы двунаправленного или произвольного доступа, а ifstream, скорее всего, предлагает только пересылку, поэтому создание экземпляра шаблона завершается неудачно.

4

Другие решения

Других решений пока нет …