2013-07-04 46 views
0

我想用std::find_if遍历std::streambuf的内容相反。这包括从std::istream_iteratorstd::istreambuf_iterator构建std::reverse_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; 
     ^

感谢您的帮助!

+0

请告诉我编译错误? – Borgleader

+0

@Borgleader我刚刚编辑了问题以包含编译错误。 –

+0

向后迭代流?并非所有的流都能够“倒带”,所以我怀疑是否有一种非常通用的方式来做到这一点。 – John3136

回答

4

据我知道输入迭代(如那些ifstreams的)不能够倒退这就是为什么反向迭代不可用。这是有道理的,因为如果你考虑它,reverse_iterator(即operator ++)的前向是正常迭代器(即operator - )的后面,所以如果正常迭代器不提供operator - ,那么它坚持认为reverse_iterator不应该存在。

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

正如你可以看到随机访问迭代器提供了双向迭代(及以上)谁自己提供前向迭代器(及以上)的所有操作的所有操作。这意味着随机访问迭代器可以用于需要前向迭代器的地方,但反过来,不是

正如你可能已经从这个解释make_reverse_iterator猜测最有可能要求或者双向或随机访问迭代器和ifstream的最有可能只提供前进这就是为什么模板实例失败。

+0

嗯,我认为'std :: istream_iterator'可以通过'sungetc'支持'operator - '。 Boost是否提供了一个类似的接口,可以用来向后迭代'std :: streambuf'? –

+0

我真的不知道增强是否提供了这样的东西,但它是一个很好的地方看,如果有人提供它会是他们。另外,对于'sungetc' * *我认为*只适用于最后一个字符的阅读,所以你可以做一次,然后你必须再次开始前进。 – Borgleader