我有以下代码:
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个值不同吗?
答案 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的基础:
->
执行此代码后,可以认为事情看起来像 这样:
这张照片不错,显示了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个差异。