std::advance - cppreference.com
De cppreference.com
| Definido en el archivo de encabezado |
||
|
|
(hasta C++17) | |
|
|
(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.
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.
| ||
Valor de retorno
(ninguno)
Complejidad
Lineal.
Sin embargo, si InputIt cumple con los requisitos de RandomAccessIterator, la complejidad es constante.
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.
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; } } } |
Ejemplo
#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: