【问题标题】:Make a c++ iterator that traverses 2 containers制作一个遍历 2 个容器的 c++ 迭代器
【发布时间】:2010-10-28 11:03:53
【问题描述】:

我需要一个如下所示的“容器”。它有 2 个子容器,称为 A 和 B,我需要能够仅迭代 A、B 以及 A 和 B 的组合。我不想为冗余数据使用额外的空间,所以我想制作自己的迭代器来迭代 A 和 B 的组合。制作自己的迭代器的最简单方法是什么?或者,还有什么方法可以做到这一点?

编辑最终,我不认为这是一个好的设计。我重新设计了整个班级层次结构。 +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;
}

【问题讨论】:

    标签: c++ iterator


    【解决方案1】:

    我将重新发布我对类似问题的回答。我认为这会做你想要的。

    使用像 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;
    

    如果您正在迭代一个索引,您可以使用库中的迭代器投影概念切换到另一个索引。

    【讨论】:

    • Boost.MultiIndex 似乎没有办法排除元素。
    【解决方案2】:

    拥有一个容器来存储您感兴趣的值以及一个指示它是在 A 还是 B 中的标志。

    【讨论】:

      【解决方案3】:

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

      比利3

      【讨论】:

        猜你喜欢
        • 2016-09-03
        • 1970-01-01
        • 2019-07-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多