好的,所以這不是一個完整的解決方案 - 但我用完了時間。所以這當前不是一個完整的迭代器,而是一個類似於這個接口的類似於迭代器的類,它需要C++ 11。我已經測試了G ++ 4.7:
template<typename NestedContainerType, typename Terminator>
class flatten_iterator
{
bool complete();
void advance();
Terminator& current();
};
哪裏NestedContainerType
是嵌套容器類型(奇怪)和終結者的,你想擺脫扁平化的最裏面東西的類型。
下面的代碼工作,但是這當然沒有廣泛測試。完全包裝它(假設你只對快速前進感到滿意)不應該做太多工作,特別是如果你使用boost::iterator_facade
。
#include <list>
#include <deque>
#include <vector>
#include <iostream>
template<typename ContainerType, typename Terminator>
class flatten_iterator
{
public:
typedef flatten_iterator<typename ContainerType::value_type, Terminator> inner_it_type;
typedef typename inner_it_type::value_type value_type;
public:
flatten_iterator() {}
flatten_iterator(ContainerType& container) : m_it(container.begin()), m_end(container.end())
{
skipEmpties();
}
bool complete()
{
return m_it == m_end;
}
value_type& current()
{
return m_inner_it.current();
}
void advance()
{
if (!m_inner_it.complete())
{
m_inner_it.advance();
}
if (m_inner_it.complete())
{
++m_it;
skipEmpties();
}
}
private:
void skipEmpties()
{
while (!complete())
{
m_inner_it = inner_it_type(*m_it);
if (!m_inner_it.complete()) break;
++m_it;
}
}
private:
inner_it_type m_inner_it;
typename ContainerType::iterator m_it, m_end;
};
template<template<typename, typename ...> class ContainerType, typename Terminator, typename ... Args>
class flatten_iterator<ContainerType<Terminator, Args...>, Terminator>
{
public:
typedef typename ContainerType<Terminator, Args...>::value_type value_type;
public:
flatten_iterator() {}
flatten_iterator(ContainerType<Terminator, Args...>& container) :
m_it(container.begin()), m_end(container.end())
{
}
bool complete()
{
return m_it == m_end;
}
value_type& current() { return *m_it; }
void advance() { ++m_it; }
private:
typename ContainerType<Terminator, Args...>::iterator m_it, m_end;
};
並與下面的測試情況下,它確實你所期望的:
int main(int argc, char* argv[])
{
typedef std::vector<int> n1_t;
typedef std::vector<std::deque<short> > n2_t;
typedef std::list<std::vector<std::vector<std::vector<double> > > > n4_t;
typedef std::vector<std::deque<std::vector<std::deque<std::vector<std::list<float> > > > > > n6_t;
n1_t n1 = { 1, 2, 3, 4 };
n2_t n2 = { {}, { 1, 2 }, {3}, {}, {4}, {}, {} };
n4_t n4 = { { { {1.0}, {}, {}, {2.0}, {} }, { {}, {} }, { {3.0} } }, { { { 4.0 } } } };
n6_t n6 = { { { { { {1.0f}, {}, {}, {2.0f}, {} }, { {}, {} }, { {3.0f} } }, { { { 4.0f } } } } } };
flatten_iterator<n1_t, int> i1(n1);
while (!i1.complete())
{
std::cout << i1.current() << std::endl;
i1.advance();
}
flatten_iterator<n2_t, short> i2(n2);
while (!i2.complete())
{
std::cout << i2.current() << std::endl;
i2.advance();
}
flatten_iterator<n4_t, double> i4(n4);
while (!i4.complete())
{
std::cout << i4.current() << std::endl;
i4.advance();
}
flatten_iterator<n6_t, float> i6(n6);
while (!i6.complete())
{
std::cout << i6.current() << std::endl;
i6.advance();
}
}
所以打印每個容器類型如下:
1
2
3
4
注意,它不尚未與set
一起使用,因爲需要處理set
迭代器返回const引用的事實。爲讀者練習... :-)
哇。看起來不錯,工作,非常接近我所需要的。一個評論:我儘量使用必要的小庫。那麼'boost :: scoped_ptr'真的有必要嗎? – steffen 2012-07-12 18:35:27
'scoped_ptr'完全沒有必要。只需按值存儲迭代器即可。 – 2012-07-12 18:58:35
???我想我犯了一個愚蠢的錯誤,但行'typename inner_it_type m_inner_it;'給編譯器錯誤'預期的嵌套名稱說明符在'inner_it_type''之前 – steffen 2012-07-12 19:20:58