【问题标题】:Why we need rbegin and rend?为什么我们需要 rbegin 和 Rend?
【发布时间】:2020-09-05 06:47:24
【问题描述】:

因为我们现在有advance()prev() 来移动迭代器到前面或后面,我们已经有了begin()end()

我想知道我们是否有更好/必须前后移动反向迭代器的情况?

【问题讨论】:

  • @tadman forward_list 没有反向迭代器
  • @Caleth 够公平的。尝试考虑反向迭代器效果更好的情况。
  • 也许是一个极端情况:如果你想创建一个新容器,等于现有容器的反向

标签: c++


【解决方案1】:

算法通常采用两个迭代器来指定一系列元素。例如std::for_each:

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

如果您想让for_each 以相反的顺序迭代(注意:for_each 确实按顺序迭代)那么advanceprev 都没有任何帮助,但您可以使用反向迭代器:

std::for_each(x.rbegin(),x.rend(),foo);

【讨论】:

    【解决方案2】:

    因为使用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
    }
    

    【讨论】:

    • 另外,拳头sn-p不能使用continue(不用重新检查itv.begin())。
    【解决方案3】:

    当您有一个带有迭代器的函数模板,并希望它对数据进行反向操作时。

    例如

    std::string s = "Hello";
    std::string r(s.rbegin(), s.rend());
    std::cout << r;
    

    【讨论】:

      【解决方案4】:

      当您使用 std::for_each()std::accumulate()std::find_if() 等算法时,它们会系统地使用 ++
      如果您希望这种进展在物理上向后发生,那么相反 迭代器很有用。

      【讨论】:

        【解决方案5】:

        我想这是一种很好的做法,因为如果你从 end 开始并在 begin 结束,这似乎很奇怪。您可以使用 rbegin 轻松说出 last but one。

        vector::reverse_iterator itr1;

        for (itr1 = vec.rbegin(); itr1 < vec.rend(); itr1++) { 
        
            if (*itr1 == num) { 
        
                  vec.erase((itr1 + 1).base()); 
            } 
        }  
        

        您可以将其用作删除向量中要擦除的数字的函数

        【讨论】:

        • 是的,但是像erase这样的一些函数不能使用反向迭代器。所以我觉得在大多数情况下使用常规迭代器更安全。
        • 我认为一切都是通俗易懂的写作和容易思考
        【解决方案6】:

        需要rbegin()/rend()是因为begin()rend()不一样,而end()又不是rbegin(),看这张图来自cppreference

        这样,您可以使用从头到尾前进或从最后一个元素倒退到第一个元素的任何算法。

        【讨论】:

        • 仅供参考:如果您在深色主题中使用 Stackoverflow,您的图像具有透明背景,这会导致深色背景上的黑色文本。
        • @rubenvb 我把背景改成了白色,这样效果更好吗?
        • 对。但是你可以使用 prev(example.end()) 来到达 example.rbegin()。对于rend(),可能不能使用prev(example.begin())。
        • 当然,您可以修改任何算法来前进或后退。但通常算法不关心方向,而rbegin/rend 则不需要。
        • 您可能想解释为什么它们不一样以及为什么反向迭代器在内部将迭代器存储到下一个元素。
        【解决方案7】:

        每个都有示例。但是,更一般地说,它允许您重用 任何 算法或与前进迭代器一起工作的运算符,以执行相同的操作,但顺序相反。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-06-09
          • 2013-05-13
          • 2022-01-20
          • 2012-12-03
          • 2016-06-25
          • 2017-03-12
          • 1970-01-01
          • 2014-06-18
          相关资源
          最近更新 更多