Namespaces
Variants

std::ranges:: prev

From cppreference.net
Iterator library
Iterator concepts
Iterator primitives
Algorithm concepts and utilities
Indirect callable concepts
Common algorithm requirements
(C++20)
(C++20)
(C++20)
Utilities
(C++20)
Iterator adaptors
Range access
(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:: 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

Возвращаемое значение

1) Предшественник i .
2) n й предшественник итератора i .
3) n -й предшественник итератора i , или первый итератор, который сравнивается с 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 ( ) является 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++11)
уменьшает итератор
(шаблон функции)