【问题标题】:C++ custom collection reverse_iterator with similar behaviour to std::vector implementationC++ 自定义集合 reverse_iterator 具有与 std::vector 实现类似的行为
【发布时间】:2014-02-12 01:17:57
【问题描述】:

我有一个基于模板的自定义集合(因为我们不能在界面上使用 std::vector)。我想实现一个特定于这个集合的 reverse_iterator。下面的反向迭代器结构是嵌套在集合类中的结构。已经实现了一个迭代器(基本上是一个指向集合元素类型的指针)。这是我第一次尝试反向迭代器。

    template <typename T>
    struct reverse_iterator
    {
        typedef T::iterator iterator;
        typedef T& reference;

        inline reverse_iterator(const iterator & it):_it(it){}
        inline reverse_iterator() : _it(0x0)                {}

        inline iterator base() const                        {iterator it = _it; return --it;}

        inline reverse_iterator operator ++ ()              {return reverse_iterator(--_it);}
        inline reverse_iterator operator -- ()              {return reverse_iterator(++_it);}
        inline reverse_iterator operator ++ (int val)       {_it -= val; return reverse_iterator(_it);}
        inline reverse_iterator operator -- (int val)       {_it += val; return reverse_iterator(_it);}
        inline reverse_iterator operator += (int val)       {_it -= val; return reverse_iterator(_it);}
        inline reverse_iterator operator -= (int val)       {_it += val; return reverse_iterator(_it);}

        inline reverse_iterator operator + (int val) const  {iterator it = _it - val; return reverse_iterator(it);}
        inline reverse_iterator operator - (int val) const  {iterator it = _it + val; return reverse_iterator(it);}

        bool operator == (const iterator & other) const     {return other == base();}
        bool operator != (const iterator & other) const     {return other != base();}

        reference operator*() const {return *base();}
        iterator operator->() const {return base();}

    private:    
        iterator _it;
    };
  1. 这是可行的 reverse_iterator 还是我遗漏了什么?
  2. 可以改进吗?

【问题讨论】:

标签: c++ iterator std


【解决方案1】:

除了下面提到的事情之外,您的实现几乎与 libstdc++ 中的实现相同(v3,但仍然有些准确)。请注意,您目前缺少所有非成员函数。总而言之,您应该尝试匹配std::reverse_iterator 接口:如果您能够使用标准类型,您可以愉快地将mylab::reverse_iterator 替换为std::reverse_iterator

缺少的东西

  1. 您缺少reverse_iterator 之间的所有比较运算符,例如operator==operator!=operator&lt; 等。

奇怪的事情

这基本上是您的reverse_iterator 与标准列表不同的内容列表。

  1. 通常,前置递增/递减运算符返回一个引用 (*this),而不是一个新对象。

  2. 后递增/递减运算符不应取值:

    inline reverse_iterator operator ++ (int)       {
      reverse_iterator tmp = *this;
      ++*this; // implement post-increment in terms of pre-increment!
      // or --_it;
      return tmp;
    }
    inline reverse_iterator operator -- (int)       { ... }
    
  3. 复合赋值运算符通常也返回引用。

  4. 您的const iterator&amp; 构造函数应该是explicit,否则可能会意外混合反向迭代器和普通迭代器。
  5. 您应该使用底层迭代器作为模板参数,而不是容器类型 T

    template <typename Iterator>
    struct reverse_iterator
    {
        typedef Iterator iterator;
        typedef typename iterator_traits<Iterator>::reference reference;
        ...
    }
    

    这使您可以在iterator_traits 可以处理的任何事情上使用reverse_iterator

    template <class Iterator>
    struct iterator_traits{
      typedef typename Iterator::reference reference;
      // Add other things
    };
    
    template <class T>
    struct iterator_traits<T*>{
      typedef T & reference;
    };
    

    有了这个,你甚至可以使用reverse_iterator&lt;int *&gt; 或类似的。

  6. operator-&gt; 通常返回指向底层对象的指针,而不是中间迭代器。您可能希望将 pointer typedef 添加到您的特征和原始迭代器中。

  7. 非常不常见检查不同类型之间的相等性。删除operator==(const iterator&amp;)

【讨论】:

  • 哇!我不想错过比较运算符。我的错。 #1,#3。同意。 #2。正确的。 #4。很好的发现。 #5。我在想是否有必要将 reverse_iterator 作为模板类,因为结构使用的类型可以在集合类中的声明之前进行类型定义。 #6。同意。 #7。不知道为什么我们需要它。将审查要求。感谢您的回答!
猜你喜欢
  • 2019-03-30
  • 1970-01-01
  • 2010-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-07
  • 2014-07-08
  • 1970-01-01
相关资源
最近更新 更多