que libreria iterators iteradores iterador assigning c++ visual-c++ stl iterator

c++ - libreria - ¿Cómo incrementar un iterador por 2?



list iterator c++ (8)

Asumiendo que el tamaño de la lista puede no ser un múltiplo par del paso, debe evitar el desbordamiento:

static constexpr auto step = 2; // Guard against invalid initial iterator. if (!list.empty()) { for (auto it = list.begin(); /*nothing here*/; std::advance(it, step)) { // do stuff... // Guard against advance past end of iterator. if (std::distance(it, list.end()) > step) break; } }

Dependiendo de la implementación de la colección, el cálculo de la distancia puede ser muy lento. A continuación es óptimo y más legible. El cierre podría cambiarse a una plantilla de utilidad con el valor final de la lista pasado por referencia constante:

const auto advance = [&](list_type::iterator& it, size_t step) { for (size_t i = 0; it != list.end() && i < step; std::next(it), ++i); }; static constexpr auto step = 2; for (auto it = list.begin(); it != list.end(); advance(it, step)) { // do stuff... }

Si no hay bucle:

static constexpr auto step = 2; auto it = list.begin(); if (step <= list.size()) { std::advance(it, step); }

¿Alguien puede decirme cómo incrementar el iterador en 2?

iter++ está disponible, ¿tengo que hacer iter+2 ? ¿Cómo puedo conseguir esto?


La respuesta muy simple:

++++iter

La respuesta larga:

Deberías acostumbrarte a escribir ++iter lugar de iter++ . Este último debe devolver (una copia de) el valor anterior, que es diferente del nuevo valor; esto toma tiempo y espacio.

Tenga en cuenta que el incremento de prefijo ( ++iter ) toma un valor l y devuelve un valor l, mientras que el incremento postfix ( iter++ ) toma un valor l y devuelve un valor r.


Podemos usar tanto el avance como el siguiente. Pero, hay una diferencia entre los dos. "avanzar" modifica su argumento y no devuelve nada. Por lo tanto, se puede utilizar como:

vector<int> v; v.push_back(1); v.push_back(2); auto itr = v.begin(); advance(itr, 1); //modifies the itr cout << *itr<<endl //prints 2

"siguiente" devuelve una copia modificada del iterador

vector<int> v; v.push_back(1); v.push_back(2); cout << *next(v.begin(), 1) << endl; //prints 2


Puede usar el operador ''asignación por adición''

iter += 2;


Si no sabe si tiene suficientes elementos siguientes en su contenedor o no, debe verificar el final de su contenedor entre cada incremento. Ni ++ ni std :: advance lo harán por usted.

if( ++iter == collection.end()) ... // stop if( ++iter == collection.end()) ... // stop

Incluso puede rodar su propia función de avance de límite consolidado.

Si está seguro de que no pasará del final, entonces std :: advance (iter, 2) es la mejor solución.


Si no tiene un valor l modificable de un iterador, o si desea obtener una copia de un iterador dado (dejando el original sin modificar), entonces C ++ 11 viene con nuevas funciones auxiliares - std::next / std::prev :

std::next(iter, 2); // returns a copy of iter incremented by 2 std::next(std::begin(v), 2); // returns a copy of begin(v) incremented by 2 std::prev(iter, 2); // returns a copy of iter decremented by 2


std::advance( iter, 2 );

Este método funcionará para los iteradores que no son iteradores de acceso aleatorio, pero la implementación aún puede especializarlo para que sea menos eficiente que iter += 2 cuando se usa con iteradores de acceso aleatorio.


http://www.cplusplus.com/reference/std/iterator/advance/

std::advance(it,n);

donde n es 2 en tu caso.

La belleza de esta función es que, si "it" es un iterador de acceso aleatorio, el rápido

it += n

se usa la operación (es decir, vector <,,> :: iterador). De lo contrario, se procesa para

for(int i = 0; i < n; i++) ++it;

(es decir, lista <..> :: iterador)