在C++11中实现自定义迭代器

3

我正在阅读一本书,开始学习模板章节。我已经阅读了迭代器的章节。为了练习,我正在尝试使用模板实现一个双向链表类。下面是我的类的头文件。

template<typename T>
class list
{
private:
    T* first_node;
    T* last_node;
    struct node_structure
    {
        T* previous;
        T* next;
        T content;
    };
public:
    list();
    void push_back( T& item );
    void push_front( T& item );
    void remove( size_t index );
    size_t size() const;
    T& get_node( size_t index );
    void clear();
    ~list();
};

我本可以设置两个成员:

T* begin();
T* end();

...表现得像非常基本的迭代器,但它们实际上并不是迭代器。所以,我有一个问题:

如何实现自定义迭代器类,以便与所有算术操作一起使用,并具有 begin()cbegin()end()cend()

(我知道创建一个列表类不会像 std::list 那样高效,但我这样做只是为了练习。)


不,Stack Overflow不是代码审查网站,但有一个是http://codereview.stackexchange.com。 - undefined
我知道。这就是为什么我将第二个问题提及为可选的,因为如果有人回答它,我就不需要在CodeReview上发布相同的内容。 - undefined
好的,那么现在我需要关于我的类的迭代器的建议,这是我帖子中的第一个问题。 - undefined
FYI,T*实际上是一个完全有效的迭代器 :) - undefined
啊,我的天哪。T* 可以作为一个类似 vector 的容器的合法迭代器。但是这是一个链表,T* 作为迭代器确实不足够。我改正我的观点。 - undefined
显示剩余3条评论
1个回答

8

如果您查看<iterator>的实现,您会发现类似于 __normal_iterator 的东西:

template<typename I>
class iter
{
protected:
    I i;

    using tr = iterator_traits<I>;

public:
    using iterator_type     = I;
    using iterator_category = typename tr::iterator_category;
    using value_type        = typename tr::value_type;
    using difference_type   = typename tr::difference_type;
    using reference         = typename tr::reference;
    using pointer           = typename tr::pointer;

    iter() : i(I()) { }

    explicit iter(const I& i) : i(i) { }

    // Forward iterator requirements
    reference operator*() const { return *i; }

    pointer operator->() const { return i; }

    iter& operator++() { ++i; return *this; }

    iter operator++(int) { return iter(i++); }

    // Bidirectional iterator requirements
    iter& operator--() { --i; return *this; }

    iter operator--(int) { return iter(i--); }

    // Random access iterator requirements
    reference operator[](const difference_type& n) const { return i[n]; }

    iter& operator+=(const difference_type& n) { i += n; return *this; }

    iter operator+(const difference_type& n) const { return iter(i + n); }

    iter& operator-=(const difference_type& n) { i -= n; return *this; }

    iter operator-(const difference_type& n) const { return iter(i - n); }

    const I& base() const { return i; }
};

这应该适用于普通指针或迭代器。您只需将其用作模板,并根据自定义容器所需进行调整。如果T是您的value_type,则成员函数通常返回:
  • begin() -> iter<T*>
  • cbegin() -> iter<const T*>
  • rbegin() -> std::reverse_iterator<iter<T*>>
  • crbegin() -> std::reverse_iterator<iter<const T*>>
然而,由于您拥有自己的node_structure,这不完全正确,您需要更详细地解释一下。

看起来有点复杂:)我会尽力处理的!谢谢 - undefined
这是另一个要欣赏std::list的原因! - undefined
阅读我在帖子中的最后一行:D 这只是为了练习而已。 - undefined
@Victor 此外,还有二进制比较运算符 ==!=,以及 <<= 等用于随机访问的操作符,这是我忘记提到的。 - undefined
我会自己尝试弄清楚 :) - undefined
1
@Victor 为了练习,你可以跳过类型特性,限制自己使用运算符*()++()(而不是++(int))和!=。这已经足够在一个for循环中看到它的作用了。还有,忘记rbegin()等函数吧,只要实现begin()end()即可。玩的开心! - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接