我如何以优雅和高效的方式实现各种迭代器类别? [英] How can I implement various iterator categories in an elegant and efficient way?

查看:120
本文介绍了我如何以优雅和高效的方式实现各种迭代器类别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在实现STL容器,例如vector。我困惑我是迭代器的实现。

I'm implementing STL containers, for example, vector. What confused me is the implementation of iterators.

如果我想实现所有迭代器类别:input_iterator,output_iterator,forward_iterator,bidirectional_iterator和random_access_iterator。

If I want to implement all iterator categories: input_iterator, output_iterator, forward_iterator, bidirectional_iterator and random_access_iterator.

如何管理他们的继承关系?
我阅读了如何实现STL式迭代器,避免常见的陷阱? -

How do I manage their inheritance relationships? I've read How to implement an STL-style iterator and avoid common pitfalls?-Mooing Duck's Answer

这是他的例子符号:

iterator {
    iterator(const iterator&);
    ~iterator();
    iterator& operator=(const iterator&);
    iterator& operator++(); //prefix increment
    reference operator*() const;
    friend void swap(iterator& lhs, iterator& rhs); //C++11 I think
};
input_iterator : public virtual iterator {
    iterator operator++(int); //postfix increment
    value_type operator*() const;
    pointer operator->() const;
    friend bool operator==(const iterator&, const iterator&);
    friend bool operator!=(const iterator&, const iterator&); 
};
//once an input iterator has been dereferenced, it is 
//undefined to dereference one before that.
output_iterator : public virtual iterator {
    reference operator*() const;
    iterator operator++(int); //postfix increment
};
//dereferences may only be on the left side of an assignment
//once an input iterator has been dereferenced, it is 
//undefined to dereference one before that.
forward_iterator : input_iterator, output_iterator {
    forward_iterator();
};
//multiple passes allowed
bidirectional_iterator : forward_iterator {
    iterator& operator--(); //prefix increment
    iterator operator--(int); //postfix decrement
};

random_access_iterator : bidirectional_iterator {
    friend bool operator<(const iterator&, const iterator&);
    friend bool operator>(const iterator&, const iterator&);
    friend bool operator<=(const iterator&, const iterator&);
    friend bool operator>=(const iterator&, const iterator&);

    iterator& operator+=(size_type);
    friend iterator operator+(const iterator&, size_type);
    friend iterator operator+(size_type, const iterator&);
    iterator& operator-=(size_type);  
    friend iterator operator-(const iterator&, size_type);
    friend difference_type operator-(iterator, iterator);

    reference operator[](size_type) const;
};



< 从类 random_access_iterator 中的,我使用代码 random_access_iterator b = a + 1 。这将导致编译错误。因为 a + 1 的类是基础迭代器,而不是 random_access_iterator

But I found a problem: If I have an instance a from class random_access_iterator, I use the code random_access_iterator b = a + 1. This will cause compile error. Because a + 1's class is base iterator, not random_access_iterator.

所以我不认为这是一个合理的解决方案。

So I don't think this is a reasonable solution.

我误解了吗?

感谢

推荐答案

我认为您应该使用CRTP( https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern )。
像这样:

I think you should use CRTP (https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). Like this:

template <typename T, typename ItT>
struct iiterator_t {
    typedef T value_type;
    typedef T& reference;
    typedef T* pointer;

    typedef ItT iterator_type;

    virtual iterator_type& operator=(const iterator_type&) = 0;
    virtual iterator_type& operator++() = 0;
    virtual reference operator*() const = 0;
};

template <typename T, typename ItT>
struct iterator_impl_t :  virtual public iiterator_t<T, ItT>{
    typedef T value_type;
    typedef T& reference;
    typedef T* pointer;

    typedef ItT iterator_type;

    iterator_type& operator=(const iterator_type &rhs)
    {
        p = static_cast<const iterator_impl_t&>(rhs).p;
        return dynamic_cast<iterator_type&>(*this);
    }

    iterator_type& operator++()
    {
        ++p;
        return dynamic_cast<iterator_type&>(*this);
    }

    reference operator*() const
    {
        return *p;
    }

private:
    pointer p;
};

template <typename T, typename ItT>
struct iinput_iterator_t : public virtual iiterator_t<T, ItT> {
    typedef T value_type;
    typedef T& reference;
    typedef T* pointer;

    typedef ItT iterator_type;

    virtual iterator_type operator++(int) = 0;
};


template <typename T, typename ItT>
struct input_iterator_impl_t :
    public virtual iinput_iterator_t<T, ItT>,
    public virtual iterator_impl_t<T, ItT>
{
    typedef T value_type;
    typedef T& reference;
    typedef T* pointer;

    typedef ItT iterator_type;

    iterator_type operator++(int)
    {
        iterator_type result(dynamic_cast<const iterator_type &>(*this));
        ++dynamic_cast<iterator_impl_t<T, ItT> &>(*this);
        return result;
    }
};


template <typename T>
struct iterator :
    public virtual iterator_impl_t<T, iterator<T> >
{
};


template <typename T>
struct input_iterator :
    public virtual input_iterator_impl_t<T, input_iterator<T>>
{
};

int main(int , char** )
{
    iterator<int> i;
    iterator<int> i2 = ++i;
    input_iterator<int> inpi;
    input_iterator<int> inpi2 = inpi++;
    return 0;
 }

这篇关于我如何以优雅和高效的方式实现各种迭代器类别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆