比较两个不同的boost :: iterator_facade迭代器

时间:2013-06-17 20:13:12

标签: c++ boost iterator

我有两个迭代器,它们都来自boost :: iterator_facade(但不是彼此之间)并且我希望能够比较它们,因为我不想在一个足够的时候有更多的end()方法。有可能吗?

以下最小例子对我不起作用,但我认为应该如此。我做错了什么?

#include <vector>
#include <iostream>

#include <boost/iterator/iterator_facade.hpp>

using namespace std;

typedef vector<int>         val_type;
typedef vector<val_type>    vec_type;

class myiterator
  : public boost::iterator_facade<
        myiterator
      , val_type
      , boost::forward_traversal_tag
    >
{
private:
    friend class boost::iterator_core_access;
    friend class base_myiterator;

public:
    explicit myiterator(vec_type::iterator _it)
        : it(_it)
    {}

    myiterator(myiterator const& other)
        : it(other.it)
    {}

 private:
    void increment() { ++it; }

    bool equal(myiterator const& other) const
    {
        return (it == other.it);
    }

    val_type& dereference() const { return *it; }

    vec_type::iterator it;
};

class base_myiterator
  : public boost::iterator_facade<
        base_myiterator
      , val_type
      , boost::forward_traversal_tag
    >
{
private:
    friend class boost::iterator_core_access;

public:
    explicit base_myiterator(vec_type::const_iterator _it, val_type _base)
      : base(_base),
        it(_it)
    {
        idx.resize(base.size());
    }

    base_myiterator(base_myiterator const& other)
      : base(other.base),
        it(other.it)
    {
        idx.resize(base.size());
    }

 private:

    void increment()
    {
        ++it;
        for (size_t i=0; i<base.size(); ++i)
        {
            idx[i] = base[i] + (*it)[i];
        }
    }

    bool equal(base_myiterator const& other) const
    {
        return (it == other.it);
    }

    bool equal(myiterator const& other) const
    {
        return (it == other.it);
    }

    val_type const& dereference() const
    {
        return idx;
    }

    val_type base;
    vec_type::const_iterator it;
    val_type idx;
};

struct Sample
{
    vec_type vec;

    myiterator begin()
    {
        return myiterator(vec.begin());
    }

    base_myiterator begin(val_type const& base)
    {
        return base_myiterator(vec.begin(), base);
    }

    myiterator end()
    {
        return myiterator(vec.end());
    }
};

int main ()
{
    Sample s;

    val_type val;
    val.push_back(1); val.push_back(0);
    s.vec.push_back(val);
    val.clear(); val.push_back(0); val.push_back(1);
    s.vec.push_back(val);

    val.clear(); val.push_back(-5); val.push_back(5);

    //for (myiterator it=s.begin(); it!=s.end(); ++it)
    for (base_myiterator it=s.begin(val); it!=s.end(); ++it)
    {
        cout << (*it)[0] << " " << (*it)[1] << endl;
    }
}

1 个答案:

答案 0 :(得分:2)

boost :: iterator_facade在实例化关系运算符之前检查两个迭代器是否为interoperable

它使用boost::type_traits::is_convertible来检查将一种类型的迭代器转换为另一种类型是否合法。因此,如果您添加构造函数base_myiterator(myiterator const& other),它将起作用。它将使用您提供的特殊等重载而不进行任何转换(即不使用额外的复制构造函数,只需要在那里)。

此外,base_myiterator似乎作为某种const_iterator(val_type const& reference() const)运行。在这种情况下,您应该将val_type const作为模板参数值传递给iterator_facade,如here所述。