【问题标题】:Compare vector<T>::iterator with vector<T>::reverse_iterator比较 vector<T>::iterator 和 vector<T>::reverse_iterator
【发布时间】:2013-02-18 14:59:56
【问题描述】:

我正在做一个练习,我有一个向量,我正在编写自己的反向算法,方法是使用反向和正常(正向)迭代器来反转向量的内容。但是,我无法比较迭代器。

int vals[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
vector<int> numbers(vals, vals + 10);

vector<int>::iterator       start = numbers.begin();
vector<int>::reverse_iterator end = numbers.rend();

我有一个先前的算法,用于通过使用两个迭代器来反转向量,但是在这个任务中,我无法使用它们之间的 != 运算符来比较它们。我的猜测是获取向量中的底层指针或索引,但我如何获取指针/索引?

【问题讨论】:

  • 对于您的练习,使用两个前向迭代器会更容易:for (vector&lt;int&gt;::iterator i = numbers.begin(), j = numbers.end(); i &lt; j; ++i) { --j; std::iter_swap(i,j); }

标签: c++ vector stl iterator


【解决方案1】:

使用base()返回的迭代器进行比较:it == rit.base() - 1

【讨论】:

  • 不过要小心。如果rit 是一个结束迭代器(即反向迭代的结束),那么rit.base()numbers.begin() 并且它是UB 从中减去1。另一种方法是比较distance(numbers.begin(), it) == distance(rit, numbers.rend()) - 1
  • @SteveJessop:当然还有- 1不能应用于一般的BidirectionalIterators而只能应用于RandomAccessIterators的问题,所以@wilx提供的代码不适用于list .
  • 建议it==std::prev(rit.base())删除随机访问要求
  • @exa:这是对涉及向量迭代器的特定问题的回答。虽然一般来说,按照自己的方式去做可能是个好主意,但在这种情况下没有必要。我相信大多数人都会设法自己进行概括。
【解决方案2】:

您可以通过调用base()reverse_iterator 转换为iterator

但是要小心,因为有一些警告。 @Matthieu M. 的评论特别有帮助:

注意:base() 实际上会返回一个iterator 给元素以下 reverse_iterator 指向的元素。

【讨论】:

  • 注意:base() 实际上返回一个iterator 到元素跟随 reverse_iterator 指向的元素。
  • @Matthieu M.:是的,这是我要写的主要警告——但既然你已经这样做了,我认为我不必再这样做了。谢谢!
  • @TobySpeight:你是对的,所以我现在就是这么做的。
【解决方案3】:

结帐http://en.cppreference.com/w/cpp/iterator/reverse_iterator/base

rit.base()

返回一个“普通”迭代器。

【讨论】:

    【解决方案4】:

    您可以使用(&amp;*start == &amp;*(end - 1)) 直接比较迭代器指向的地址。

    【讨论】:

    • 您可以...但是您应该这样做吗? :)
    • 这没有回答问题。 OP 询问如何将迭代器与 reverse_iterator 进行比较,而不是如何比较 start 和 end-1 元素的地址。
    【解决方案5】:

    这两种类型无法比较(这是一个非常好的主意),在我看来,调用.base() 不是很优雅(或通用)。 您可以转换类型并比较结果。 考虑到涉及reverse_iterators 的一对一规则。

    iteratorreverse_iterator 的转换需要显式(幸运),但是,从reverse_iterator 到迭代器的转换是不可能的(不幸的是)。 所以只有一种方法可以进行转换然后进行比较。

        std::vector<double> vv = {1.,2.,3.};
        auto it = vv.begin();
        auto rit = vv.rend();
    //  assert( it == rit ); // error: does not compile
        assert(std::vector<double>::reverse_iterator{it} == rit);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多