为什么我们需要 rbegin 和 rend?

3

现在我们有了 advance()prev() 方法可以将迭代器前进或后退,同时我们已经有了 begin()end() 方法。

我想知道是否存在一些情况下需要前进或后退反向迭代器?


@tadman,forward_list没有反向迭代器。 - Caleth
@Caleth 好的。我在思考哪种情况下反向迭代器更好用。 - tadman
也许是一个边缘情况:如果您想创建一个新容器,它等于现有容器的反转。 - Damien
7个回答

8

算法通常需要两个迭代器来指定一段元素的范围。例如 std::for_each

std::vector<int> x;
std::for_each(x.begin(),x.end(),foo);

如果您想让for_each在反向迭代中运行(注意:for_each会按顺序迭代),那么既不需要使用advance也不需要使用prev,但可以使用反向迭代器:
std::for_each(x.rbegin(),x.rend(),foo);

4

因为使用 begin()end() 进行反向迭代看起来很糟糕:

std::vector<int> v {1, 2, 3};
if(!v.empty()) { //need to make sure of that before we decrement
    for(auto it = std::prev(v.end()); ; --it) {
        //do something with it
        if(it == v.begin()) {
            break;
        }
    }
}

与反向迭代器版本进行比较:

std::vector<int> v {1, 2, 3};
for(auto it = v.rbegin(); it != v.rend(); it++) {
    //do something with it
}

1
此外,第一个代码片段不能使用 continue(而不重新检查 itv.begin() 的关系)。 - Jarod42

1
当您使用像std::for_each()std::accumulate()std::find_if()这样的算法时,它们会按照++的方式进行系统化进展。
如果您希望此进展在物理上向后发生,则反向迭代器非常有用。

1
我想这是一个好的练习,因为如果你从结尾开始并在开头结束,看起来很奇怪。你可以使用rbegin轻松地说出倒数第二个。
vector::reverse_iterator itr1;
for (itr1 = vec.rbegin(); itr1 < vec.rend(); itr1++) { 

    if (*itr1 == num) { 

          vec.erase((itr1 + 1).base()); 
    } 
}  

你可以使用一个函数来删除向量中想要删除的数字。

是的,但是一些函数(如erase)不能使用反向迭代器。因此,在大多数情况下,我觉得使用常规迭代器更安全。 - Michael
我认为一切都是可理解的写作和易于思考。 - onur

1
由于 begin()rend() 不同,end() 也不等同于 rbegin(),因此需要使用 rbegin()/rend()。请参考这张来自cppreference的图片。

enter image description here

这样,您可以从头到尾使用任何算法,也可以从最后一个元素向后使用任何算法。

2
只是提醒一下:您的图像具有透明背景,如果您在黑暗主题下查看Stackoverflow,则会导致黑色文本出现在深色背景上。 - rubenvb
@rubenvb,我把背景改成了白色,这样效果更好吗? - Olaf Dietsche
没错。但是你可以使用prev(example.end())来到达example.rbegin()。对于rend(),可能不能使用prev(example.begin())。 - Michael
你可以修改任何算法使其前进或后退。但通常算法不关心方向,并且使用rbegin/rend就没有必要了。 - Olaf Dietsche
你可能想解释一下它们为什么不同,以及为什么反向迭代器在内部存储一个指向下一个元素的迭代器。 - Evg

1
当您拥有一个接受迭代器的函数模板,并希望它对数据进行反向操作时。
例如:
std::string s = "Hello";
std::string r(s.rbegin(), s.rend());
std::cout << r;

0

有使用 for each 的示例。然而,更一般地,它允许您重用任何与迭代器前进一起工作的算法或运算符,以相反的顺序执行相同的操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接