std::advance
De cppreference.com
Definido en el archivo de encabezado <iterator>
|
||
template<typename InputIt, typename Distance> void advance( InputIt& it, Distance n ); |
(hasta C++17) | |
template<typename InputIt, typename Distance> constexpr void advance( InputIt& it, Distance n ); |
(desde C++17) | |
Incrementa un iterador dado it
en n
elementos.
Si n
is negativa, el iterador se decrementa. En este caso, InputIt
debe de satisfacer los requisitos de BidirectionalIterator, de otra forma el comportamiento no está definido.
Contenido |
[editar] Parámetros
it | - | Iterador a avanzar. |
n | - | Número de elementos en los que it se debe avanzar.
|
Requisitos de tipo | ||
-InputIt debe satisfacer los requisitos de InputIterator.
|
[editar] Valor de retorno
(ninguno)
[editar] Complejidad
Lineal.
Sin embargo, si InputIt
cumple con los requisitos de RandomAccessIterator, la complejidad es constante.
[editar] Notas
El comportamiento no está definido si la secuencia especificada de incrementos o decrementos requiriera que se incremente un iterador no incrementable (como el iterador posterior al final), o que un iterador no decrementable (como el iterador frontal o el iterador singular) se decrementa.
[editar] Posible implementación
Véanse también las implementaciones en libstdc++ y libc++.
Versión no constexpr |
---|
namespace detail { template<class It> void do_advance(It& it, typename std::iterator_traits<It>::difference_type n, std::input_iterator_tag) { while (n > 0) { --n; ++it; } } template<class It> void do_advance(It& it, typename std::iterator_traits<It>::difference_type n, std::bidirectional_iterator_tag) { while (n > 0) { --n; ++it; } while (n < 0) { ++n; --it; } } template<class It> void do_advance(It& it, typename std::iterator_traits<It>::difference_type n, std::random_access_iterator_tag) { it += n; } } // namespace detail template<class It, class Distance> void advance(It& it, Distance n) { detail::do_advance(it, typename std::iterator_traits<It>::difference_type(n), typename std::iterator_traits<It>::iterator_category()); } |
Versión constexpr |
template<class It, class Distance> constexpr void advance(It& it, Distance n) { using category = typename std::iterator_traits<It>::iterator_category; static_assert(std::is_base_of_v<std::input_iterator_tag, category>); auto dist = typename std::iterator_traits<It>::difference_type(n); if constexpr (std::is_base_of_v<std::random_access_iterator_tag, category>) it += dist; else { while (dist > 0) { --dist; ++it; } if constexpr (std::is_base_of_v<std::bidirectional_iterator_tag, category>) while (dist < 0) { ++dist; --it; } } } |
[editar] Ejemplo
Ejecuta este código
#include <iostream> #include <iterator> #include <vector> int main() { std::vector<int> v{3, 1, 4}; auto vi = v.begin(); std::advance(vi, 2); std::cout << *vi << ' '; vi = v.end(); std::advance(vi, -2); std::cout << *vi << '\n'; }
Salida:
4 1
[editar] Véase también
(C++11) |
Incrementa un iterador. (función) |
(C++11) |
Decrementa un iterador. (función) |
Devuelve la distancia entre dos iteradores. (función) | |
(C++20) |
Avanza un iterador en una distancia dada o a un límite dado. (niebloid) |