我想使用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;
^
感谢您的帮助!
答案 0 :(得分:4)
据我所知,输入迭代器(例如ifstreams的迭代器)不能倒退,这就是反向迭代器不可用的原因。这是有道理的,因为如果你考虑它,reverse_iterator(即operator ++)的前进是正常迭代器(即运算符 - )的向后,所以如果正常迭代器不提供运算符 - 那么它理所当然地说,reverse_iterator不应该存在。
我记得有三种类型的迭代器:前向,双向和随机访问。前向只能向一个方向(猜测哪个:P),双向可以前进和后退1,随机访问可以前进和后退任何增量。
正如您所看到的,随机访问迭代器提供了双向迭代器(以及更多)的所有操作,这些操作本身提供了前向迭代器的所有操作(以及更多)。这意味着随机访问迭代器可以在需要前向迭代器的地方使用,但不是相反。
正如您可能从这个解释中猜到的那样,make_reverse_iterator很可能需要双向或随机访问迭代器,而ifstream最有可能只提供转发,这就是模板实例化失败的原因。