std::ranges:: prev
|
Определено в заголовке
<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) |
Возвращает n -й предшественник итератора i .
Описываемые на этой странице функциональные объекты являются algorithm function objects (неформально известными как niebloids ), то есть:
- Явные списки аргументов шаблона не могут быть указаны при вызове любого из них.
- Ни один из них не видим для argument-dependent lookup .
- Когда любой из них найден с помощью normal unqualified lookup как имя слева от оператора вызова функции, argument-dependent lookup блокируется.
Содержание |
Параметры
| i | - | итератор |
| n | - | количество элементов, на которое i должен быть уменьшен |
| bound | - | итератор, обозначающий начало диапазона, на который указывает i |
Возвращаемое значение
Сложность
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
(
)
является rvalue-выражением, и в требованиях к итераторам не указано, что декремент rvalue гарантированно будет работать. В частности, когда итераторы реализованы как указатели или их
operator--
имеет lvalue-ref-квалификатор,
--
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)
|
уменьшает итератор
(шаблон функции) |