迭代器值与转换后的反向迭代器值不同

时间:2012-04-29 16:24:45

标签: c++ stl iterator

我有以下代码:

int main()
{
    vector<int> v;

    for(int i = 0; i < 10; ++i)
        v.push_back(i);

    auto it = v.begin() + 3;

    cout << "Iterator: " << *it << endl;

    vector<int>::reverse_iterator revIt(it);

    cout << "Reverse iterator: " << *revIt << endl;

}

运行此代码后,我得到以下输出:

Iterator: 3
Reverse iterator: 2

有人可以解释为什么2个值不同吗?

4 个答案:

答案 0 :(得分:5)

反向迭代器'对应'到base迭代器,偏移量为一个元素,因为rbegin()rend()必须使用有效的基础迭代器来表示{{1分别是}和end()。例如,begin()不能由在容器的rend()迭代器之前“指向”的交互器表示,尽管这是逻辑上代表的。所以begin()的'基础迭代器'是rend()。因此,begin()的基础迭代器变为rbegin()。 反向迭代器在取消引用时会自动调整该偏移量(使用end()*运算符)。

旧的article by Scott Meyers详细解释了这种关系以及一张漂亮的图片:

  

准则3:了解如何使用reverse_iterator的基础迭代器

     

在reverse_iterator上调用基本成员函数会产生   “相应的”迭代器,但这并不是很清楚这意味着什么。   举个例子,看看这个代码,它将数字1-5放入   向量,设置reverse_iterator指向3,并设置一个   迭代器到reverse_iterator的基础:

->
     

执行此代码后,可以认为事情看起来像   这样:

     

alt text

     

这张照片不错,显示了a的特征偏移   reverse_iterator及其相应的基本迭代器,模仿   关于begin()和end()的rbegin()和rend()的偏移量,但是   它没有告诉你需要知道的一切。特别是它   没有解释如何使用i来执行您想要的操作   在ri上演出。

答案 1 :(得分:4)

看起来documentation表示他们这样做是为了处理过去的元素,即如果你反转一个超过结束的迭代器,新的反向迭代器指向最后一个元素。

答案 2 :(得分:2)

24.5.1反向迭代器的第一段说:

  

类模板reverse_iterator是一个迭代器适配器,它从其底层迭代器定义的序列的末尾迭代到该序列的开头。反向迭代器与其对应的迭代器之间的基本关系由身份建立:
  &*(reverse_iterator(i)) == &*(i - 1)

rend()返回的值不能指向begin()之前,因为它无效。因此决定rend()应该包含begin()的值,并且所有其他反向迭代器将进一步移位一个位置。 operator*会对此进行补偿,并且无论如何都会访问正确的元素。

答案 3 :(得分:1)

反向迭代器看起来始终是“一个之前”然后是前向,因为它的范围被移动了一个:

前进迭代器从begin()(第一个元素)到end()(过去的最后一个:[begin-end]在末尾打开)

根据定义,反向迭代器从rbegin() { return reverse_iterator(end()); }变为rend() { return reverse_iterator(begin()); },但也必须走开具有rbegin的开放范围[rbegin-rend]作为最后一个(不是“过去的最后一个”)和rend为了“在第一个”之前(而不是“第一个”),因此可以容纳1个差异。