◐ Shell
clean mode source ↗

std::ranges::next - cppreference.com

De cppreference.com

Definido en el archivo de encabezado <iterator>

Signatura de la llamada

template< std::input_or_output_iterator I > constexpr I next( I i );

(1) (desde C++20)

template< std::input_or_output_iterator I > constexpr I next( I i, std::iter_difference_t<I> n );

(2) (desde C++20)

template< std::input_or_output_iterator I, std::sentinel_for<I> S > constexpr I next( I i, S bound );

(3) (desde C++20)

template< std::input_or_output_iterator I, std::sentinel_for<I> S > constexpr I next( I i, std::iter_difference_t<I> n, S bound );

(4) (desde C++20)

Devuelve el nésimo sucesor del iterador i.

Las entidades similares a funciones descritas en esta página son niebloids, es decir:

En la práctica, pueden implementarse como objetos función o con extensiones de compilador especiales.

Parámetros

it - Un iterador.
n - Número de elementos a avanzar.
bound - Centinela que denota el fin del rango al que apunta i.

Valor de retorno

1) El sucesor del iterador i.

2) El nésimo sucesor del iterador i.

3) El primer iterador equivalente a bound.

4) El nésimo sucesor del iterador i, o el primer iterador equivalente a bound, lo que suceda primero.

Complejidad

1) Constante.

2) Constante si I modela std::random_access_iterator; lineal de lo contrario.

3) Constante si I y S modela a std::random_access_iterator<I> y std::sized_sentinel_for<S, I>, o si I y S modela std::assignable_from<I&, S>; lineal de lo contrario.

4) Constante si I y S modela a std::random_access_iterator<I> y std::sized_sentinel_for<S, I>; lineal de lo contrario.

Posible implementación

struct next_fn
{
    template<std::input_or_output_iterator I>
    constexpr I operator()(I i) const
    {
        ++i;
        return i;
    }

    template<std::input_or_output_iterator I>
    constexpr I operator()(I i, std::iter_difference_t<I> n) const
    {
        ranges::advance(i, n);
        return i;
    }

    template<std::input_or_output_iterator I, std::sentinel_for<I> S>
    constexpr I operator()(I i, S bound) const
    {
        ranges::advance(i, bound);
        return i;
    }

    template<std::input_or_output_iterator I, std::sentinel_for<I> S>
    constexpr I operator()(I i, std::iter_difference_t<I> n, S bound) const
    {
        ranges::advance(i, n, bound);
        return i;
    }
};

inline constexpr auto next = next_fn();

Notas

Aunque la expresión ++x.begin() suele compilarse, no se garantiza que lo haga: x.begin() es una expresión r-valor y no hay ningún requisito que especifique que se garantice que el incremento de un r-valor funcione. En particular, cuando los iteradores se implementan como punteros o su operator++ está calificado como referencia a l-valor, ++x.begin() no compila, mientras que ranges::next(x.begin()) sí.

Ejemplo

#include <cassert>
#include <iterator>

int main() 
{
    auto v = {3, 1, 4};
    {
        auto n = std::ranges::next(v.begin());
        assert(*n == 1);
    }
    {
        auto n = std::ranges::next(v.begin(), 2);
        assert(*n == 4);
    }
    {
        auto n = std::ranges::next(v.begin(), v.end());
        assert(n == v.end());
    }
    {
        auto n = std::ranges::next(v.begin(), 42, v.end());
        assert(n == v.end());
    }
}

Véase también