可能重复:
展平迭代器
我有某种类型的向量(比如int)。我想遍历向量中的元素集合,就像遍历整数向量一样。
我可以实现一些可以做到这一点的东西,但想知道如何使用 boost 的 iterator_adapter 来做到这一点。
这是我破解的东西。它可以工作并输出正确的结果,但还有很多工作要做。
#include <boost/iterator/iterator_adaptor.hpp>
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <string>
template <typename Iter>
class flattening_iterator :
public boost::iterator_adaptor<
flattening_iterator<Iter>,
Iter,
typename Iter::value_type::iterator::value_type,
boost::forward_traversal_tag,
typename Iter::value_type::iterator::value_type
>
{
private:
using super_t = boost::iterator_adaptor<
flattening_iterator<Iter>,
Iter,
typename Iter::value_type::iterator::value_type,
boost::forward_traversal_tag,
typename Iter::value_type::iterator::value_type
>;
using inner_iterator = typename Iter::value_type::iterator;
public:
flattening_iterator(Iter it)
: super_t(it),
inner_begin(),
inner_end(),
outer_end(it)
{}
flattening_iterator(Iter begin, Iter end)
: super_t(begin),
inner_begin((*begin).begin()),
inner_end((*begin).end()),
outer_end(end)
{}
using value_type = typename Iter::value_type::iterator::value_type;
private:
friend class boost::iterator_core_access;
inner_iterator inner_begin;
inner_iterator inner_end;
Iter outer_end;
void increment()
{
if (this->base_reference() == outer_end)
return; // At the end
++inner_begin;
if (inner_begin == inner_end)
{
++this->base_reference();
inner_begin = (*this->base_reference()).begin();
inner_end = (*this->base_reference()).end();
}
}
value_type dereference() const
{
return *inner_begin;
}
};
template <typename Iter>
auto flatten(Iter it) -> flattening_iterator<Iter>
{
return flattening_iterator<Iter>(it);
}
template <typename Iter>
auto flatten(Iter begin, Iter end) -> flattening_iterator<Iter>
{
return flattening_iterator<Iter>(begin, end);
}
int main()
{
std::vector<std::vector<int>> v1{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
for (auto i = flatten(v1.begin(), v1.end()); i != flatten(v1.end()); ++i)
{
std::cout << *i << ' ';
}
std::cout << std::endl;
std::vector<std::vector<std::string>> v2{{"Hello", "Print"}, {"Me", "Here"}};
std::copy(flatten(v2.begin(), v2.end()), flatten(v2.end()),
std::ostream_iterator<std::string>(std::cout, " "));
}