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.
Parmetros
| it | - | Iterador a avanzar. |
| n | - | Nmero 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 implementacin
Vanse tambin las implementaciones en libstdc++ y libc++.
| Versin 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());
}
|
| Versin 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
Ejecuta este cdigo
#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
Vase tambin
(C++11) |
Incrementa un iterador. (funcin) |
(C++11) |
Decrementa un iterador. (funcin) |
| Devuelve la distancia entre dos iteradores. (funcin) | |
(C++20) |
Avanza un iterador en una distancia dada o a un lmite dado. (niebloid) |