2009-05-23 9 views
3

私は以下のように機能する "コンテナ"が必要です。それにはAとBと呼ばれる2つのサブコンテナがあり、A、B、AとBを繰り返し処理する必要があります。私は冗長データ用に余分なスペースを使いたくないので、AとBを組み合わせて反復するための独自のイテレータを作成することを考えました。独自のイテレータを作る最も簡単な方法は何ですか?または、これを行う別の方法は何ですか?2つのコンテナを横断するC++イテレータを作成する

EDIT最終的に、私は良いデザインだとは思わない。私はクラス階層全体を再設計しました。 +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

はそれが私は同様の質問に私の答えを再投稿しますAまたはB

0

また、std :: pair <>オブジェクトを含む単一のコンテナを作成することもできます。

Billy3

関連する問題