2009-05-23 2 views
3

다음과 같이 작동하는 "컨테이너"가 필요합니다. A와 B라는 2 개의 하위 컨테이너가 있으며 A, B 및 A와 B를 결합하여 반복 할 수 있어야합니다. 여분의 데이터에 여분의 공간을 사용하고 싶지 않기 때문에 A와 B를 반복하여 반복 할 자체 반복자를 만드는 방법을 생각했습니다. 자체 반복자를 만드는 가장 쉬운 방법은 무엇입니까? 또는, 이것을하는 또 다른 방법은 무엇입니까?2 컨테이너를 탐색하는 C++ 반복자 만들기

편집 궁극적으로 나는 좋은 디자인이라고 생각하지 않습니다. 나는 전체 계층의 계층 구조를 재 설계했다. +1 리팩토링. 그러나, 나는이 문제를 충분히 풀었다. 다음은 참조 용으로 제가 한 일의 약식 버전입니다. boost :: filter_iterator를 사용합니다. T를 컨테이너의 유형이라고합시다.

enum Flag 
{ 
    A_flag, 
    B_flag 
}; 

class T_proxy 
{ 
public: 
    T_proxy(const T& t, Flag f) : t_(t), flag_(f) {} 
    operator T() const {return t_;} 
    Flag flag() const {return flag_;} 
    class Compare 
    { 
    public: 
     Compare(Flag f) : matchFlag_(f) {} 
     operator() (const T_proxy& tp) {return tp.flag() == matchFlag_;} 
    private: 
     Flag matchFlag_; 
    }; 
private: 
    T t_; 
    Flag flag_; 
}; 

class AB_list 
{ 
public: 
    typedef T_proxy::Compare Compare; 
    typedef vector<T_proxy>::iterator iterator; 
    typedef boost::filter_iterator<Compare, iterator> sub_iterator; 
    void insert(const T& val, Flag f) {data_.insert(T_proxy(val, f));} 
    // other methods... 

    // whole sequence 
    iterator begin() {return data_.begin();} 
    iterator end() {return data_.end();} 

    // just A 
    sub_iterator begin_A() {return sub_iterator(Compare(A_flag), begin(), end()); 
    sub_iterator end_A() {return sub_iterator(Compare(A_flag), end(), end()); 

    // just B is basically the same 
private: 
    vector<T_proxy> data_; 
}; 


// usage 
AB_list mylist; 
mylist.insert(T(), A_flag); 
for (AB_list::sub_iterator it = mylist.begin_A(); it != mylist.end_A(); ++it) 
{ 
    T temp = *it; // T_proxy is convertible to T 
    cout << temp; 
} 

답변

7

과 함께 관심있는 값을 저장 한 용기를 가지고. 나는 이것이 당신이 원하는 것을 할 것이라고 생각합니다.

Boost.MultiIndex과 같은 라이브러리를 사용하여 원하는대로 할 수 있습니다. 새로운 지표를 추가하고 싶다면 보일러 플레이트 코드가 훨씬 적습니다. 그것은 일반적으로 more space and time efficient

typedef multi_index_container< 
    Container, 
    indexed_by< 
    sequenced<>, //gives you a list like interface 
    ordered_unique<Container, std::string, &Container::a_value>, //gives you a lookup by name like map 
    ordered_unique<Container, std::string, &Container::b_value> //gives you a lookup by name like map 
    > 
> container; 

당신이 하나 개의 인덱스 반복하는 경우 라이브러리에서 반복자 투사 개념을 사용하여 다른 인덱스로 전환 할 수도있다.

+0

Boost.MultiIndex에는 요소를 제외하는 방법이없는 것 같습니다. – rlbond

0

는 플래그 내가 비슷한 질문에 대한 내 대답을 재 게시됩니다 그것은에 있는지 여부를 나타내는 또는 B

0

std :: pair <> 개체가 포함 된 단일 컨테이너를 만들 수도 있습니다.

빌리 3