Espacios de nombres
Variantes
Acciones

std::ranges::distance

De cppreference.com
< cpp‎ | iterator
 
 
Biblioteca de iteradores
Conceptos de iteradores
Primitivas de iteradores
Conceptos de algoritmos y servicios
Conceptos invocables indirectos
Requerimientos comunes de algoritmos
Servicios
Adaptadores de iteradores
Iteradores de flujos
Puntos de personalización de iteradores
Operaciones de iteradores
(C++11)
(C++11)
ranges::distance
(C++20)
Acceso a rangos
(C++11)(C++14)
(C++11)(C++14)
(C++17)(C++20)
(C++14)(C++14)
(C++14)(C++14)
(C++17)
(C++17)
 
Definido en el archivo de encabezado <iterator>
Signatura de la llamada
template< class I, std::sentinel_for<I> S >

    requires (!std::sized_sentinel_for<S, I>)
constexpr std::iter_difference_t<I>

    distance( I first, S last );
(1) (desde C++20)
template< class I, std::sized_sentinel_for<std::decay_t<I>> S >

constexpr std::iter_difference_t<std::decay_t<I>>

    distance( I&& first, S last );
(2) (desde C++20)
template< ranges::range R >

constexpr ranges::range_difference_t<R>

    distance( R&& r );
(3) (desde C++20)
1,2) Devuelve la cantidad de saltos desde first hasta last.
3) Devuelve el tamaño de r como un entero con signo.

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.

Contenido

[editar] Parámetros

first - Iterador que apunta al primer elemento.
last - Centinela que denota el final del rango del que first es un iterador.
r - Rango del que calcular la distancia.

[editar] Valor de retorno

1) La cantidad de incrementos necesarios para pasar de first a last.
2) last - static_cast<const std::decay_t<I>&>(first).
3) Si R modela ranges::sized_range, devuelve ranges::size(r); de lo contrario, ranges::distance(ranges::begin(r), ranges::end(r)).

[editar] Complejidad

1) Lineal.
2) Constante.
3) Si R modela ranges::sized_range o si se modela std::sized_sentinel_for<ranges::sentinel_t<R>, ranges::iterator_t<R>>, la complejidad es constante; de ​​lo contrario, lineal.

[editar] Posible implementación

struct distance_fn
{
    template<class I, std::sentinel_for<I> S>
        requires (!std::sized_sentinel_for<S, I>)
    constexpr std::iter_difference_t<I> operator()(I first, S last) const
    {
        std::iter_difference_t<I> result = 0;
        while (first != last)
        {
            ++first;
            ++result;
        }
        return result;
    }
 
    template<class I, std::sized_sentinel_for<std::decay<I>> S>
    constexpr std::iter_difference_t<I> operator()(const I& first, S last) const
    {
        return last - first;
    }
 
    template<ranges::range R>
    constexpr ranges::range_difference_t<R> operator()(R&& r) const
    {
        if constexpr (ranges::sized_range<std::remove_cvref_t<R>>)
            return static_cast<ranges::range_difference_t<R>>(ranges::size(r));
        else
            return (*this)(ranges::begin(r), ranges::end(r));
    }
};
 
inline constexpr auto distance = distance_fn{};

[editar] Ejemplo

#include <cassert>
#include <forward_list>
#include <iterator>
#include <vector>
 
int main() 
{
    std::vector<int> v{3, 1, 4};
    assert(std::ranges::distance(v.begin(), v.end()) == 3);
    assert(std::ranges::distance(v.end(), v.begin()) == -3);
    assert(std::ranges::distance(v) == 3);
 
    std::forward_list<int> l{2, 7, 1};
    // auto size = std::ranges::size(l); // ERROR: no es un rango considerable
    auto size = std::ranges::distance(l); // De acuerdo, considera la complejidad O(N)
    assert(size == 3);
}


[editar] Informes de defectos

Los siguientes informes de defectos de cambio de comportamiento se aplicaron de manera retroactiva a los estándares de C++ publicados anteriormente.

ID Aplicado a Comportamiento según lo publicado Comportamiento correcto
LWG 3392 C++20 La sobrecarga (1) toma el iterador por valor, por lo tanto, se rechazó
el iterador l-valor de solo movimiento con un centinela dimensionado.
Se añadió la sobrecarga (2)
LWG 3664 C++20 La resolución de Asunto LWG 3392 hizo que
ranges::distance rechazara argumentos tipo array.
Los acepta.

[editar] Véase también

Avanza un iterador en una distancia dada o a un límite dado.
(niebloid) [editar]
Devuelve el número de elementos que cumplan con un criterio específico.
(niebloid) [editar]
Devuelve la distancia entre dos iteradores.
(función) [editar]