std::ranges::prev

Header: <iterator>

Return the nth predecessor of iterator i.

# Declarations

Call signature
template< std::bidirectional_iterator I >
constexpr I prev( I i );

(since C++20)

template< std::bidirectional_iterator I >
constexpr I prev( I i, std::iter_difference_t<I> n );

(since C++20)

template< std::bidirectional_iterator I >
constexpr I prev( I i, std::iter_difference_t<I> n, I bound );

(since C++20)

# Parameters

# Notes

Although the expression –r.end() often compiles for containers, it is not guaranteed to do so: r.end() is an rvalue expression, and there is no iterator requirement that specifies that decrement of an rvalue is guaranteed to work. In particular, when iterators are implemented as pointers or its operator– is lvalue-ref-qualified, –r.end() does not compile, while ranges::prev(r.end()) does.

This is further exacerbated by ranges that do not model ranges::common_range. For example, for some underlying ranges, ranges::transform_view::end doesn’t have the same return type as ranges::transform_view::begin, and so –r.end() won’t compile. This isn’t something that ranges::prev can aid with, but there are workarounds.

# Example

#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';
}

# See also