2011-07-12 68 views
6

下面是一个STL容器的相当正常的封装,它允许Cfoo的用户迭代容器而不允许更改内部容器。迭代封装的嵌套STL容器

#include <vector> 

class Cfoo 
{ 
public: 
    class Cbar 
    { 
     /* contents of Cbar */ 
    }; 
    typedef std::vector<Cbar> TbarVector; 
    typedef TbarVector::const_iterator const_iterator;  
public: 
    const_iterator begin() const { return(barVector_.begin()); } 
    const_iterator end() const { return(barVector_.end()); } 
private: 
    TbarVector barVector_; 
}; 

到目前为止,这么好。我们可以遍历容器是这样的:

Cfoo myFoo; 
for (Cfoo::const_iterator it = myFoo.begin(); it != myFoo.end(); ++it) 
{ 
    it->DoSomething(); 
} 

现在我想讲一个嵌套的std ::向量更换的std ::向量:

public: 
    typedef std::vector<Cbar> TbarVectorInner; 
    typedef std::vector<TbarVectorInner> TbarVectorOuter; 

private: 
    TbarVectorOuter barContainer_; 

但我希望能够遍历所有的Cbar实例与之前一样,暴露了一个const_iterator,以及一个begin()const和一个end()const方法。

我不清楚该怎么做,但我怀疑它涉及到编写一个自定义迭代器。有什么想法吗?

+1

它涉及编写自定义迭代器。 –

+2

听起来像Flatten Iterator的工作从http://stackoverflow.com/questions/3623082/flattening-iterator – Cubbi

+0

TbarVector应该是私人的,它告诉外部世界与它无关的东西,容易被误用。 –

回答

4

没有一个标准迭代器能够迭代多个容器,所以你的假设是正确的 - 你必须编写一个自定义迭代器。

如果您有一个将(开始,结束)迭代器对返回到内部容器的中间迭代器,那么可以以通用方式完成此操作。

一些未经测试的代码开始:

template<typename T, typename OuterIterator, typename InnerIterator> 
class Iterator2d : std::Iterator 
{ 
public: 
    Iterator2d(OuterIterator begin, OuterIterator end) : m_begin(begin), m_end(end), m_currentOuter(begin) { 
     if (m_currentOuter != m_end) 
      m_currentInner = m_begin->first; 
     Normalize(); 
    } 
    Iterator2d & operator++() 
    { 
     if (m_currentOuter != m_end) 
     { 
      ++m_currentInner; 
      Normalize(); 
     } 
     return *this; 
    } 
    T & operator*() 
    { 
     return *m_currentInner; 
    } 
private: 
    void Normalize() 
    { 
     while (m_currentOuter != m_end && m_currentInner == m_currentOuter->second) 
     { 
      ++m_currentOuter; 
      if (m_currentOuter != m_end) 
       m_currentInner = m_currentOuter->first; 
     } 
    } 

    OuterIterator m_begin; 
    OuterIterator m_end; 
    OuterIterator m_currentOuter; 
    InnerIterator m_currentInner; 
}; 

这仅仅是一个开始,我会回来完成它 - 与否,取决于this implementation已经涵盖同样的理由。

+0

'operator ++()'错过'return * this' – teivaz

+0

@teivaz谢谢,修正。 –