【问题标题】:What's the difference between std::advance and std::next?std::advance 和 std::next 有什么区别?
【发布时间】:2013-02-07 15:37:19
【问题描述】:

除了提前取负数之外还有更多吗?

【问题讨论】:

    标签: c++ c++11 std


    【解决方案1】:

    std::advance

    • 修改其参数
    • 不返回任何内容
    • 适用于输入迭代器或更好的迭代器(如果给定负距离,则为双向迭代器)

    std::next

    • 保持其参数不变
    • 返回参数的副本,按指定数量提前
    • 适用于前向迭代器或更好的迭代器(或双向迭代器,如果给出负距离))

    【讨论】:

    • 我不认为你碰巧知道他们为什么在非前向迭代器的输入迭代器上使用next,即使next 的定义效果保证有效在输入迭代器上?
    • @HowardHinnant:啊,谢谢。所以基本上,如果你正在使用 InputIterator,那么你应该只使用++(或advance,以保护自己免受涉及next 的单行代码带来的毁灭性便利),或者编写你自己的my_next可能与您的实现的std::next 相同,可能删除了特征断言。我突然想到,在同一个论点上,InputIterator 不应该需要operator++(int)。我想现在解决这个问题为时已晚。
    • 如果我有一台时间机器,我会拿走 InputIterator 的复制构造函数并使其只能移动。我认为这会让它们更安全、更容易推理。
    • std::next 上的额外约束已被 cplusplus.github.io/LWG/lwg-defects.html#2353 取消
    【解决方案2】:

    也许最大的实际区别是std::next() 仅适用于 C++11。

    std::next() 默认前进一格,而std::advance() 需要一段距离。

    然后是返回值:

    std::next()std::advance 一样采用负数,在这种情况下要求迭代器必须是双向的。当意图专门向后移动时,std::prev() 将更具可读性。

    【讨论】:

    • next 不仅向前发展,在这方面就像advance。鉴于prev 的存在,使用否定文字编写next(it, -1) 可能很奇怪。但是对于正确类别的迭代器,即使 it2 > it3 也可以编写 next(it, distance(it2, it3))
    • @SteveJessop:感谢您的编辑和对可读性的强调。
    • @Johnsyweb std::next() 在 C++11 之后可用,不仅在 C++11 中可用。
    • 谢谢@John。九年前我写的时候答案是正确的。
    【解决方案3】:

    std::advance

    Advance() 函数增加作为参数传递的迭代器的位置。因此,该函数让迭代器前进(或后退)多个元素:

    #include <iterator>
    void advance (InputIterator& pos, Dist n)
    
    • 让输入迭代器 pos 向前(或向后)步进 n 个元素。
    • 对于双向和随机访问迭代器,n 可能为负数以向后退。
    • Dist 是一个模板类型。通常,它必须是整数类型,因为诸如
    • 请注意,advance() 不会检查它是否与序列的 end() 相交(它无法检查,因为迭代器通常不知道 它们操作的容器)。因此,调用此函数可能 导致未定义的行为,因为最后调用运算符 ++ 未定义序列。

    std::next(和std::prev C++11 中的新功能)

    #include <iterator>
    ForwardIterator next (ForwardIterator pos)
    ForwardIterator next (ForwardIterator pos, Dist n)
    
    • 如果向前移动 1 或 n 个位置,则产生向前迭代器 pos 将具有的位置。
    • 对于双向和随机访问迭代器,n 可能为负数以产生先前的位置。
    • Dist 是 std::iterator_traits::difference_type 类型。
    • 为内部临时对象调用 Advance(pos,n)。
    • 请注意,next() 不会检查它是否穿过序列的 end()。因此,由调用者来确保结果是 有效。

    引用The C++ Standard Library Second Edition

    【讨论】:

      【解决方案4】:

      它们几乎相同,只是 std::next 返回一个副本,std::advance 修改其参数。请注意,标准要求std::next 的行为类似于std::advance

      24.4.4 迭代器操作 [iterator.operations]

      template <class InputIterator, class Distance>
      void advance(InputIterator& i [remark: reference], Distance n);
      

      2。要求:仅对于双向和随机访问迭代器,n 应为负
      3. 效果:将迭代器引用 i 递增(或负 n 递减)n。
      [...]

      template <class ForwardIterator>
      ForwardIterator next(ForwardIterator x, [remark: copy]
           typename std::iterator_traits<ForwardIterator>::difference_type n = 1);
      

      6。效果:相当于advance(x, n); return x;

      请注意,如果迭代器是输入迭代器,两者实际上都支持负值。另请注意,std::next 要求迭代器满足 ForwardIterator 的条件,而 std::advance 只需要输入迭代器(如果您不使用负距离)。

      【讨论】:

        猜你喜欢
        • 2014-07-22
        • 2023-04-09
        • 2020-10-16
        • 2020-09-30
        • 2021-10-16
        • 2015-07-18
        • 2019-02-26
        • 2020-04-25
        相关资源
        最近更新 更多