2011-07-12 26 views
6

Đây là một đóng gói khá bình thường của một container STL cho phép người dùng của Cfoo để iterate container mà không cho phép thay đổi bên trong.iterating đóng gói container STL lồng nhau

#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_; 
}; 

Cho đến nay, rất tốt. Chúng ta có thể lặp container như thế này:

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

Bây giờ tôi muốn thay thế std :: vector với nói một std :: vector lồng nhau:

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

private: 
    TbarVectorOuter barContainer_; 

Nhưng tôi muốn có thể để lặp qua tất cả các cá thể của Cbar theo cùng cách như trước, để lộ ra một hàm const_iterator, và một phương thức start() const và một phương thức end() const.

Tôi không rõ làm thế nào để làm điều đó, mặc dù tôi nghi ngờ nó liên quan đến việc viết một iterator tùy chỉnh. Có suy nghĩ gì không?

+1

Nó liên quan đến việc viết một trình vòng lặp tùy chỉnh. –

+2

Âm thanh như công việc cho Flattening Iterator từ http://stackoverflow.com/questions/3623082/flattening-iterator – Cubbi

+0

'TbarVector' nên là riêng tư, nó nói với những điều thế giới bên ngoài không liên quan đến nó và dễ bị lạm dụng . –

Trả lời

4

Không có trình vòng lặp chuẩn nào có thể lặp qua nhiều hơn một vùng chứa duy nhất, do đó giả thiết của bạn là chính xác - bạn sẽ phải viết một trình vòng lặp tùy chỉnh.

Có thể thực hiện điều này theo kiểu chung, nếu bạn có trình lặp trung gian trả về các cặp lặp (bắt đầu, kết thúc) cho các thùng chứa bên trong.

Một số mã chưa được kiểm tra để bắt đầu:

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; 
}; 

này chỉ là một sự khởi đầu, tôi có thể trở lại để kết thúc nó - hay không, tùy thuộc vào this implementation đã bao gồm cùng một mặt bằng.

+0

'toán tử ++()' nhớ 'trả về * this' – teivaz

+0

@teivaz cảm ơn, cố định. –