std:: distance
|
Definido en el encabezado
<iterator>
|
||
|
template
<
class
InputIt
>
typename
std::
iterator_traits
<
InputIt
>
::
difference_type
|
(constexpr desde C++17) | |
Devuelve el número de saltos desde first hasta last .
Si
InputIt
no es
LegacyRandomAccessIterator
, el comportamiento es indefinido si
last
no es
alcanzable
desde
first
.
Si
InputIt
es un
LegacyRandomAccessIterator
, el comportamiento es indefinido si
first
y
last
no son accesibles uno desde el otro.
Contenidos |
Parámetros
| first | - | iterador que apunta al primer elemento |
| last | - | iterador que apunta al final del rango |
| Requisitos de tipo | ||
-
InputIt
debe cumplir con los requisitos de
LegacyInputIterator
. La operación es más eficiente si
InputIt
adicionalmente cumple con los requisitos de
LegacyRandomAccessIterator
.
|
||
Valor de retorno
El número de incrementos necesarios para ir desde first hasta last .
|
El valor puede ser negativo si se utilizan iteradores de acceso aleatorio y first es accesible desde last . |
(desde C++11) |
Complejidad
Lineal.
Sin embargo, si
InputIt
cumple adicionalmente con los requisitos de
LegacyRandomAccessIterator
, la complejidad es constante.
Implementación posible
Consulte también las implementaciones en libstdc++ y libc++ .
| Implementación C++98 mediante tag dispatch, con constexpr eliminado |
|---|
namespace detail { template<class It> constexpr // requerido desde C++17 typename std::iterator_traits<It>::difference_type do_distance(It first, It last, std::input_iterator_tag) { typename std::iterator_traits<It>::difference_type result = 0; while (first != last) { ++first; ++result; } return result; } template<class It> constexpr // requerido desde C++17 typename std::iterator_traits<It>::difference_type do_distance(It first, It last, std::random_access_iterator_tag) { return last - first; } } // namespace detail template<class It> constexpr // desde C++17 typename std::iterator_traits<It>::difference_type distance(It first, It last) { return detail::do_distance(first, last, typename std::iterator_traits<It>::iterator_category()); } |
| Implementación C++17 mediante if constexpr |
template<class It> constexpr typename std::iterator_traits<It>::difference_type distance(It first, It last) { using category = typename std::iterator_traits<It>::iterator_category; static_assert(std::is_base_of_v<std::input_iterator_tag, category>); if constexpr (std::is_base_of_v<std::random_access_iterator_tag, category>) return last - first; else { typename std::iterator_traits<It>::difference_type result = 0; while (first != last) { ++first; ++result; } return result; } } |
Ejemplo
#include <iostream> #include <iterator> #include <vector> int main() { std::vector<int> v{3, 1, 4}; std::cout << "distance(first, last) = " << std::distance(v.begin(), v.end()) << '\n' << "distance(last, first) = " << std::distance(v.end(), v.begin()) << '\n'; // el comportamiento es indefinido (hasta LWG940) static constexpr auto il = {3, 1, 4}; // Desde C++17 `distance` puede usarse en contexto constexpr. static_assert(std::distance(il.begin(), il.end()) == 3); static_assert(std::distance(il.end(), il.begin()) == -3); }
Salida:
distance(first, last) = 3 distance(last, first) = -3
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.
| DR | Aplicado a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| LWG 940 | C++98 | la redacción no era clara para el caso donde first es alcanzable desde last | aclarado |
Véase también
|
avanza un iterador una distancia dada
(plantilla de función) |
|
|
devuelve el número de elementos que cumplen criterios específicos
(plantilla de función) |
|
|
(C++20)
|
devuelve la distancia entre un iterador y un centinela, o entre el inicio y fin de un rango
(objeto función de algoritmo) |