std::ranges::advance
来自cppreference.com
在标头 <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) 自增给定的迭代器
i
n 次。2) 自增给定的迭代器
i
直至 i == bound。3) 自增给定的迭代器
i
n 次,或直至 i == bound,取决于何者先达成。若 n 为负数,则自减迭代器。此情况下,I
必须实现 std::bidirectional_iterator,而若提供了 bound 则 S
必须与 I
为同一类型,否则行为未定义。
此页面上描述的函数式实体是算法函数对象(非正式地称为 niebloid),即:
目录 |
[编辑]参数
i | - | 要推进的迭代器 |
bound | - | 哨位,代表 i 作为迭代器所指向的范围的结尾 |
n | - | i 应自增的次数 |
[编辑]返回值
3)n 与 i 所遍历的实际距离之间的差。
[编辑]复杂度
线性。
然而,若 I
额外实现 std::random_access_iterator,或若 S
实现 std::sized_sentinel_for<I>,或若 I
与 S
实现 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
[编辑]参阅
(C++20) | 自增迭代器给定的距离或到边界 (算法函数对象) |
(C++20) | 自减迭代器给定的距离或到边界 (算法函数对象) |
(C++20) | 返回迭代器与哨位间的距离,或范围起始与结尾间的距离 (算法函数对象) |
令迭代器前进给定的距离 (函数模板) |