std::ranges::prev
来自 cppreference.cn
定义于头文件 <iterator> |
||
调用签名 |
||
template< std::bidirectional_iterator I > constexpr I prev( I i ); |
(1) | (始于 C++20) |
template< std::bidirectional_iterator I > constexpr I prev( I i, std::iter_difference_t<I> n ); |
(2) | (始于 C++20) |
template< std::bidirectional_iterator I > constexpr I prev( I i, std::iter_difference_t<I> n, I bound ); |
(3) | (始于 C++20) |
返回迭代器 i 的第 n 个前驱。
本页描述的形似函数的实体是算法函数对象(非正式地称为 niebloid),即
内容 |
[编辑] 参数
i | - | 一个迭代器 |
n | - | i 应当回退的元素数量 |
bound | - | 指示 i 所指向的范围的起始的迭代器 |
[编辑] 返回值
1) i 的前驱。
2) 迭代器 i 的第 n 个前驱。
3) 迭代器 i 的第 n 个前驱,或首个与 bound 比较相等的迭代器,取先到者。
[编辑] 复杂度
1) 常数。
2,3) 如果 I 建模
std::random_access_iterator<I>
,则为常数;否则为线性。[编辑] 可能的实现
struct prev_fn { template<std::bidirectional_iterator I> constexpr I operator()(I i) const { --i; return i; } template<std::bidirectional_iterator I> constexpr I operator()(I i, std::iter_difference_t<I> n) const { ranges::advance(i, -n); return i; } template<std::bidirectional_iterator I> constexpr I operator()(I i, std::iter_difference_t<I> n, I bound) const { ranges::advance(i, -n, bound); return i; } }; inline constexpr auto prev = prev_fn(); |
[编辑] 注释
尽管表达式 --r.end()
对于容器而言经常编译通过,但不保证总是如此:r.end()
是一个右值表达式,并且没有迭代器要求指定保证右值的自减能工作。 特别是当迭代器实现为指针或其 operator--
是左值引用限定时,--r.end()
不会编译,而 ranges::prev(r.end())
则会。
对于不建模 ranges::common_range
的范围,情况会进一步恶化。 例如,对于某些底层范围,ranges::transform_view::end
不具有与 ranges::transform_view::begin
相同的返回类型,因此 --r.end()
将不会编译。 这不是 ranges::prev
可以帮助解决的问题,但存在一些变通方法。
[编辑] 示例
运行此代码
#include <iostream> #include <iterator> #include <vector> int main() { std::vector<int> v{3, 1, 4}; auto pv = std::ranges::prev(v.end(), 2); std::cout << *pv << '\n'; pv = std::ranges::prev(pv, 42, v.begin()); std::cout << *pv << '\n'; }
输出
1 3
[编辑] 参见
(C++20) |
将迭代器按给定距离或到边界递增 (算法函数对象) |
(C++20) |
将迭代器按给定距离或到给定边界推进 (算法函数对象) |
(C++11) |
递减迭代器 (函数模板) |