2012-04-29 72 views
1

完成之后的我有以下代码:迭代器值从反向迭代值转换

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

我不是100%确定的,但前向迭代器会向前看,而反向迭代器会回头看。 'v = {1,2,* 3,4 ...}'其中*是它们两者的迭代器位置。看看他们要走哪个方向。 – chris

+0

@chris:不完全是:或者更好,这是java如何定义迭代器(指向“之间”)C++有不同的概念。但实际结果也是按照你的解释。但结果是,而不是定义。 –

+0

@EmilioGaravaglia,谢谢你的清理。这不是我所熟悉的。 – chris

回答

5

反向迭代“对应”到base迭代用,因为如何rbegin()rend()必须使用碱迭代器是有效的(end()begin()分别)表示一种元素的偏移量。例如,rend()不能由在容器的迭代器之前'指向'的interator表示,尽管这是它在逻辑上表示的内容。所以rend()的'基本迭代器'是begin()。因此,rbegin()的基本迭代器变为end()。 反向迭代器在解除引用时会自动调整该偏移量(使用*->运算符)。

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

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

调用一个reverse_iterator的收益率基本成员函数 “对应”的迭代器,但它不是很清楚这意味着什么。 作为一个例子,看看这个代码,这使该数字1-5中 载体中,设置一个reverse_iterator的指向3,并设置一个 迭代器reverse_iterator的碱:

vector<int> v; 

// put 1-5 in the vector 
for (int i = 1; i <= 5; ++i) { 
    v.push_back(i); 
} 

// make ri point to the 3 
vector<int>::reverse_iterator ri = 
    find(v.rbegin(), v.rend(), 3); 

// make i the same as ri's base 
vector<int>::iterator i(ri.base()); 

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

alt text

这张照片很不错,显示特性的 reverse_iterator的和correspondi偏移模仿 对于rbegin()和雷德()的偏移量开始纳克基本的迭代器()和()结束,但 它不会告诉你,你需要知道的一切。特别是, 没有解释如何使用我执行您想要在ri上执行的操作。

4

看起来像documentation表示他们这样做来处理过去结束的元素,即如果您颠倒了结束时的迭代器,新的逆向迭代器指向最后一个元素。

2

的24.5.1反向迭代器第一段表示:

类模板reverse_iterator的是一个迭代器适配器,从通过其底层迭代器限定到该序列的开头的序列的结束迭代。反向迭代器与其对应的迭代器i之间的基本关系由以下标识建立:
&*(reverse_iterator(i)) == &*(i - 1)

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

1

反向迭代看起来总是“一个之前”,然后向前,因为它的范围是由一个移动:

前向迭代从云开始()(第一个元素)end()的(过去的最后一个:开始 - 结束)在端侧敞开)

反向迭代从rbegin() { return reverse_iterator(end()); }定义去rend() { return reverse_iterator(begin()); },但也有走开放范围[rbegin,撕裂),具有rbegin是最后(不是“过去最后一个“),并倾向于在”第一个“之前(而不是”第一个“),因此需要适应一个差异。