1

我想用反向std::find_if遍历一个内容。std::streambuf这涉及std::reverse_iteratorstd::istream_iteratoror构造一个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;
          ^

谢谢你的帮助!

4

1 回答 1

4

据我所知,输入迭代器(例如 ifstreams 的那些)不能倒退,这就是反向迭代器不可用的原因。这是有道理的,因为如果您考虑一下,reverse_iterator 的前向(即运算符 ++)是普通迭代器(即运算符--)的后向,因此如果普通迭代器不提供运算符--,那么它按理说 reverse_iterator 不应该存在。

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

如您所见,随机访问迭代器提供双向迭代器(及更多)的所有操作,而双向迭代器本身提供前向迭代器(及更多)的所有操作。这意味着可以在需要前向迭代器的地方使用随机访问迭代器,但反之则不行

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

于 2013-07-04T01:33:18.147 回答