2

我有两个迭代器,它们都来自 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;
    }
}
4

1 回答 1

2

boost::iterator_facade在实例化关系运算符之前检查两个迭代器是否可互操作。

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

Furthermore, the base_myiterator seems to operate as some sort of const_iterator (val_type const& reference() const). In this case you should pass val_type const as template parameter Value to iterator_facade as described here.

于 2013-07-23T21:41:06.747 回答