我需要一个具有如下功能的“容器”。它有 2 个子容器,称为 A 和 B,我需要能够迭代 A、B 以及 A 和 B 的组合。我不想为冗余数据使用额外的空间,所以我想到制作自己的迭代器来迭代 A 和 B 的组合。制作自己的迭代器的最简单方法是什么?或者,还有什么其他方法可以做到这一点?
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;
}
我将重新发布我对类似问题的回答。我想这会做你想做的。
使用类似的库Boost.MultiIndex http://www.boost.org/doc/libs/1_39_0/libs/multi_index/doc/index.html做你想做的事。它的扩展性很好,并且如果您想添加新索引,则样板代码会少很多。通常也是这样空间和时间效率更高 http://www.boost.org/doc/libs/1_39_0/libs/multi_index/doc/performance.html
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;
如果您正在迭代一个索引,则可以使用库中的迭代器投影概念切换到另一个索引。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)