迭代迭代流

时间:2013-07-04 01:17:44

标签: c++ iterator iostream boost-iterators

我想使用std::find_if来反向遍历std::streambuf的内容。这涉及从std::reverse_iteratorstd::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 个答案:

答案 0 :(得分:4)

据我所知,输入迭代器(例如ifstreams的迭代器)不能倒退,这就是反向迭代器不可用的原因。这是有道理的,因为如果你考虑它,reverse_iterator(即operator ++)的前进是正常迭代器(即运算符 - )的向后,所以如果正常迭代器不提供运算符 - 那么它理所当然地说,reverse_iterator不应该存在。

我记得有三种类型的迭代器:前向,双向和随机访问。前向只能向一个方向(猜测哪个:P),双向可以前进和后退1,随机访问可以前进和后退任何增量。

正如您所看到的,随机访问迭代器提供了双向迭代器(以及更多)的所有操作,这些操作本身提供了前向迭代器的所有操作(以及更多)。这意味着随机访问迭代器可以在需要前向迭代器的地方使用,但不是相反。

正如您可能从这个解释中猜到的那样,make_reverse_iterator很可能需要双向或随机访问迭代器,而ifstream最有可能只提供转发,这就是模板实例化失败的原因。

相关问题