std::ranges::advance

来自cppreference.com
< cpp‎ | iterator
 
 
迭代器库
迭代器概念
迭代器原语
算法概念与工具
间接可调用概念
常用算法要求
(C++20)
(C++20)
(C++20)
工具
(C++20)
迭代器适配器
迭代器操作
(C++11)  
(C++11)
ranges::advance
(C++20)
范围访问
(C++11)(C++14)
(C++14)(C++14)  
(C++11)(C++14)
(C++14)(C++14)  
(C++17)(C++20)
(C++17)
(C++17)
 
在标头 <iterator> 定义
调用签名
template<std::input_or_output_iterator I >
constexprvoid advance( I& i, std::iter_difference_t<I> n );
(1) (C++20 起)
template<std::input_or_output_iterator I, std::sentinel_for<I> S >
constexprvoid advance( I& i, S bound );
(2) (C++20 起)
template<std::input_or_output_iterator I, std::sentinel_for<I> S >
constexprstd::iter_difference_t<I> advance( I& i, std::iter_difference_t<I> n, S bound );
(3) (C++20 起)
1) 自增给定的迭代器 in 次。
2) 自增给定的迭代器 i 直至 i == bound
3) 自增给定的迭代器 in 次,或直至 i == bound,取决于何者先达成。

n 为负数,则自减迭代器。此情况下,I 必须实现 std::bidirectional_iterator,而若提供了 boundS 必须与 I 为同一类型,否则行为未定义。

此页面上描述的函数式实体是算法函数对象(非正式地称为 niebloid),即:

目录

[编辑]参数

i - 要推进的迭代器
bound - 哨位,代表 i 作为迭代器所指向的范围的结尾
n - i 应自增的次数

[编辑]返回值

3)ni 所遍历的实际距离之间的差。

[编辑]复杂度

线性。

然而,若 I 额外实现 std::random_access_iterator,或若 S 实现 std::sized_sentinel_for<I>,或若 IS 实现 std::assignable_from<I&, S>,则复杂度为常数。

[编辑]注解

若指定的自增或自减序列会要求自增不可自增的迭代器(例如尾后迭代器),或自减不可自减的迭代器(例如首迭代器或孤立迭代器),则行为未定义。

[编辑]可能的实现

struct advance_fn {template<std::input_or_output_iterator I>constexprvoid operator()(I& i, std::iter_difference_t<I> n)const{ifconstexpr(std::random_access_iterator<I>) i += n;else{while(n >0){--n;++i;}   ifconstexpr(std::bidirectional_iterator<I>){while(n <0){++n;--i;}}}}   template<std::input_or_output_iterator I, std::sentinel_for<I> S>constexprvoid operator()(I& i, S bound)const{ifconstexpr(std::assignable_from<I&, S>) i = std::move(bound);elseifconstexpr(std::sized_sentinel_for<S, I>)(*this)(i, bound - i);elsewhile(i != bound)++i;}   template<std::input_or_output_iterator I, std::sentinel_for<I> S>constexprstd::iter_difference_t<I> operator()(I& i, std::iter_difference_t<I> n, S bound)const{ifconstexpr(std::sized_sentinel_for<S, I>){// std::abs 在 C++23 前非 constexprauto abs =[](conststd::iter_difference_t<I> x){return x <0?-x : x;};   if(constauto dist = abs(n)- abs(bound - i); dist <0){(*this)(i, bound);return-dist;}   (*this)(i, n);return0;}else{while(n >0&& i != bound){--n;++i;}   ifconstexpr(std::bidirectional_iterator<I>){while(n <0&& i != bound){++n;--i;}}   return n;}}};   inlineconstexprauto advance = advance_fn();

[编辑]示例

#include <iostream>#include <iterator>#include <vector>   int main(){std::vector<int> v {3, 1, 4};   auto vi = v.begin();   std::ranges::advance(vi, 2);std::cout<<"1) value: "<<*vi <<'\n'<<std::boolalpha;   std::ranges::advance(vi, v.end());std::cout<<"2) vi == v.end(): "<<(vi == v.end())<<'\n';   std::ranges::advance(vi, -3);std::cout<<"3) value: "<<*vi <<'\n';   std::cout<<"4) diff: "<< std::ranges::advance(vi, 2, v.end())<<", value: "<<*vi <<'\n';   std::cout<<"5) diff: "<< std::ranges::advance(vi, 4, v.end())<<", vi == v.end(): "<<(vi == v.end())<<'\n';}

输出:

1) value: 4 2) vi == v.end(): true 3) value: 3 4) diff: 0, value: 4 5) diff: 3, vi == v.end(): true

[编辑]参阅

自增迭代器给定的距离或到边界
(算法函数对象)[编辑]
自减迭代器给定的距离或到边界
(算法函数对象)[编辑]
返回迭代器与哨位间的距离,或范围起始与结尾间的距离
(算法函数对象)[编辑]
令迭代器前进给定的距离
(函数模板)[编辑]
close