代码之家  ›  专栏  ›  技术社区  ›  ThisSuitIsBlackNot Olaf Dietsche

从正向迭代器获取反向迭代器,而不知道值类型

  •  23
  • ThisSuitIsBlackNot Olaf Dietsche  · 技术社区  · 15 年前

    我正在尝试实现一些STL风格的排序算法。的原型 std::sort 看起来像这样(从 cplusplus.com ):

    template <class RandomAccessIterator>
    void sort ( RandomAccessIterator first, RandomAccessIterator last );
    

    通常这样调用函数(尽管容器类型可能不同):

    std::vector<int> myVec;
    // Populate myVec
    std::sort(myVec.begin(), myVec.end());
    

    我复制了 STD::排序 我自己的排序功能。要遍历要排序的容器,我执行以下操作:

    template <class RandomAccessIterator>
    void mySort(RandomAccessIterator first, RandomAccessIterator last) {  
      RandomAccessIterator iter;
      for (iter = first; iter != last; ++iter) {
        // Do stuff
      }
    }
    

    很简单。但是如果我想使用反向迭代器呢?这在从两端对容器进行排序的算法中很方便,例如 cocktail sort .

    有没有办法从作为参数传入的迭代器中获取反向迭代器?如果我事先知道集装箱类型,我可以这样做:

    template <class RandomAccessIterator>
    void mySort(RandomAccessIterator first, RandomAccessIterator last) {
      std::vector<int>::reverse_iterator riter(last);
      std::vector<int>::reverse_iterator rend(first);
      for ( ; riter != rend; ++riter) {
        // Do stuff
      }
    }    
    

    不幸的是,我 不要 了解容器类型。我真正需要做的是这样的事情:

    template <class RandomAccessIterator>
    void mySort(RandomAccessIterator first, RandomAccessIterator last) {
      RandomAccessIterator riter = reverse_iterator(last);
      RandomAccessIterator rend = reverse_iterator(begin);
      for ( ; riter != rend; ++riter) {
        // Do stuff
      }
    }
    

    有没有什么方法可以做到这一点而不必将反向迭代器作为附加参数传递(这可以解决问题,但会降低函数原型的直观性)?

    注意我需要两个都向前 在我的实现中反转迭代器,因此用这种方式调用函数

    std::vector<int> myVec;
    // Populate myVec
    mySort(myVec.rbegin(), myVec.rend());
    

    不会起作用。

    2 回复  |  直到 8 年前
        1
  •  29
  •   rlbond    8 年前

    STL有 std::reverse_iterator<Iterator> :

    template <class RandomAccessIterator>
    void mySort(RandomAccessIterator first, RandomAccessIterator last) 
    {
      typedef std::reverse_iterator<RandomAccessIterator> RIter;
      RIter riter(last);
      RIter rend(first);
      for ( ; riter != rend; ++riter) {
        // Do stuff
      }
    }
    

    一个 important note 以下内容:

    但是请注意,当一个迭代器 是反转的,反转的是 不指向 范围,但在它前面的范围内。 就是这样,为了安排 范围的结束元素之后: 指向结尾处的迭代器 一个范围内的元素,如果反转,则为 更改为指向最后一个元素 (不超过)范围 是范围的第一个元素,如果 颠倒)。如果一个迭代器 范围中的第一个元素是反转的, 反向迭代器指向 第一个元素之前的元素(此 将是过去的结束元素 范围(如果颠倒)。

        2
  •  -5
  •   Mike C    15 年前

    查看Reverse_迭代器的base()方法。