2009-05-23 70 views
3

我需要一个如下所示的“容器”。它有2个子容器,称为A和B,我需要能够遍历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 2009-05-23 18:04:48

0

有一个容器,它存储你有兴趣连同标志指示是否是在A或B

0

您也可以创建一个包含std :: pair对象的容器。

Billy3