【问题标题】:Get a reverse iterator from a forward iterator without knowing the value type在不知道值类型的情况下从前向迭代器获取反向迭代器
【发布时间】:2010-12-19 17:26:42
【问题描述】:

我正在尝试实现一些 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::sort 的原型。要遍历要排序的容器,我执行以下操作:

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());

不会工作。

【问题讨论】:

    标签: c++ sorting iterator


    【解决方案1】:

    查看 reverse_iterator 的 base() 方法。

    【讨论】:

    • 这让你得到了前向迭代器(这个问题所问的反向
    【解决方案2】:

    STL 有std::reverse_iterator&lt;Iterator&gt;:

    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:

    但是请注意,当迭代器 是颠倒的,颠倒的版本确实 不指向同一个元素 范围,但到它前面的那个。 就是这样,为了安排 范围的末尾元素: 一个指向过去的迭代器 范围内的元素,当反转时,是 改为指向最后一个元素 (不超过它)的范围(这将 成为范围的第一个元素 if 反转)。如果一个迭代器 范围内的第一个元素被反转, 反向迭代器指向 第一个元素之前的元素(这个 将是过去的结束元素 范围(如果反转)。

    【讨论】:

    • 我之前在文档中看到了这一点,但是当我无法使用 reverse_iterator&lt;IteratorType&gt; 编译时放弃了它。问题:我忘了添加std::(doh!)谢谢你的回答!
    • important note 确实很重要。 riter 将在物理上指向元素 after last(在向前迭代的意义上)。然而,有点违反直觉的是,*riter 确实 指向与last 相同的元素。
    • 分配riterrend 时,使用reverse_iterator。这是什么?是std::reverse_iterator吗?后者是一个类,你必须提供一个模板参数,所以代码是无效的。还是你自己定义的函数?
    • 这是一个错字。现已修复!
    • 我假设您的意思是参数firstbegin
    猜你喜欢
    • 2010-10-27
    • 1970-01-01
    • 2020-01-21
    • 2021-05-04
    • 2012-05-09
    • 1970-01-01
    • 2014-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多