我需要一个像以下一样的"容器".它有2个子容器,称为A和B,我需要能够迭代A,只有B,A和B组合.我不想为冗余数据使用额外的空间,所以我想让我自己的迭代器迭代A和B组合.制作自己的迭代器最简单的方法是什么?或者,另一种方法是什么?
编辑最终,我不认为这是好的设计.我重新设计了整个班级的heirarchy.重构+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;
}
Run Code Online (Sandbox Code Playgroud)
我将把我的答案重新发给一个类似的问题.我想这会做你想要的.
使用像Boost.MultiIndex这样的库来做你想要的.它可以很好地扩展,如果你想添加新的索引,锅炉板代码就会少得多.它通常也更节省空间和时间
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;
Run Code Online (Sandbox Code Playgroud)
如果要迭代一个索引,则可以使用库中的迭代器投影概念切换到另一个索引.
| 归档时间: |
|
| 查看次数: |
960 次 |
| 最近记录: |