¿Alguien puede decirme cómo incrementar el iterador en 2?¿Cómo incrementar un iterador en 2?
iter++
está disponible - ¿Tengo que hacer iter+2
? ¿Cómo puedo conseguir esto?
¿Alguien puede decirme cómo incrementar el iterador en 2?¿Cómo incrementar un iterador en 2?
iter++
está disponible - ¿Tengo que hacer iter+2
? ¿Cómo puedo conseguir esto?
podría utilizar el 'asignación por adición' operador
iter += 2;
Me preguntaba si ++ iter ++ funcionaría, pero creo que sería confuso. – Xetius
¿Qué pasará si el iterador señala actualmente el último elemento? ¿Dónde apuntará después del incremento? – sharptooth
@Xetius: No deberías hacerlo. Es un comportamiento indefinido. – Naveen
Este método funcionará para iteradores que no son iteradores de acceso aleatorio, pero todavía se puede especializar por la aplicación para ser no menos eficiente que iter += 2
cuando se usa con iteradores de acceso aleatorio.
¿Qué pasará si el iterador señala actualmente el último elemento? ¿Dónde apuntará después del incremento? Intenté con VC++, simplemente avanza y la comparación contra vector :: end() devuelve falso después de eso. Esta es una forma directa de comportamiento indefinido, supongo. – sharptooth
Sí, si va a hacer std :: advance con '2', o + = 2, o dos '++' sin verificar si está 'end' en el medio, entonces necesita una garantía externa de que está no va a ir más allá de uno pasado el final. (Por ejemplo, puede * saber * que está iterando a través de los elementos pares (de base cero) de una colección que garantiza tener un número par de elementos). –
cuál es la diferencia entre el siguiente (iter, 2) y el siguiente (iter, 2) – m1350
http://www.cplusplus.com/reference/std/iterator/advance/
std::advance(it,n);
donde n es 2, en su caso.
La belleza de esta función es que si "él" es un iterador de acceso aleatorio, el ayuno
it += n
operación se utiliza (es decir, el vector < ,,> :: iterador). Por lo demás es prestado a
for(int i = 0; i < n; i++)
++it;
(es decir, la lista < ..> :: iterador)
La respuesta muy simple:
++++iter
La respuesta larga:
que realmente debería tener utilizado para escribir ++iter
en 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.
Comportamiento indefinido si 'iter' es un puntero sin formato (que pueden ser algunos tipos de iteradores). '++ it; ++ it; 'estaría bien. –
Mala idea y no es muy legible. –
Por favor, dime que esta no es una respuesta seria. – Axle
Si no sabe si tiene suficientes elementos siguientes en su contenedor o no, debe comprobar contra 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 hacer rodar su propia función de avance seguro encuadernado.
Si está seguro de que no pasará del final, entonces std :: advance (iter, 2) es la mejor solución.
Si no tiene un lvalue 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
Si tengo un iterador como este: 'map
@HaniGoc Only it_tmp – metamorphosis
podemos utilizar tanto adelantado, así como el próximo. Pero, hay una diferencia entre los dos. "avance" 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
Suponiendo tamaño de la lista puede no ser un múltiplo par del paso que debe protegerse de 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 recopilación, el cálculo de la distancia puede ser muy lento. A continuación es óptimo y más legible. El cierre se podría cambiar a una plantilla de servicio con el valor de la lista final pasada por referencia const:
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 un bucle:
static constexpr auto step = 2;
auto it = list.begin();
if (step <= list.size())
{
std::advance(it, step);
}
A juzgar por la variedad de respuestas, puede que tenga que aclarar tu pregunta. – teabot
Sí. ¿Qué tipo de iterador es? Muestra un código –