print geeksforgeeks for advance c++ stl iteration

geeksforgeeks - list iterator c++



Iteración sobre un vector en dirección inversa (9)

Como ha notado, el problema con una condición de i >= 0 cuando no está firmado es que la condición siempre es verdadera. En lugar de restar 1 al inicializar i y luego nuevamente después de cada iteración, reste 1 después de verificar la condición del ciclo:

for (unsigned i = v.size(); i-- > 0; )

Me gusta este estilo por varias razones:

  • Aunque i UINT_MAX a UINT_MAX al final del ciclo, no depende de ese comportamiento; funcionaría igual si los tipos se firmaran. Depender de un envolvente sin firma me parece un poco complicado.
  • Llama a size() exactamente una vez.
  • No usa >= . Cada vez que veo ese operador en un bucle for , tengo que volver a leerlo para asegurarme de que no haya un error "uno por uno".
  • Si cambia el espaciado en el condicional, puede hacer que use el operador "goes to" .

Necesito iterar sobre un vector desde el final hasta el principio. La forma "correcta" es

for(std::vector<SomeT>::reverse_iterator rit = v.rbegin(); rit != v.rend(); ++rit) { //do Something }

Cuando doSomething implica conocer el índice real, se deben realizar algunos cálculos con rit para obtenerlo, como index = v.size() - 1 - (rit - v.rbegin)

Si el índice se necesita de todos modos, creo firmemente que es mejor iterar usando ese índice

for(int i = v.size() - 1; i >= 0; --i) { //do something with v[i] and i; }

Esto da una advertencia de que v.size() firmado y v.size() no tiene firma. Cambiando a

for(unsigned i = v.size() - 1; i >= 0; --i) es funcionalmente incorrecto, porque esto es esencialmente un ciclo sin fin :)

¿Cuál es una manera estéticamente buena de hacer lo que quiero hacer que

  • está libre de advertencia
  • no involucra moldes
  • no es excesivamente detallado

Espero no estar buscando algo que no exista :)


Creo que:

for(unsigned i = v.size() - 1; i >= 0; --i)

está bien si revisas

!v.empty()

más temprano.


Hola, creo que es mejor usar iterator como lo utilizas en la primera muestra y si necesitas obtener el índice de iterador puedes usar std :: distance para calcularlo, si entiendo tu pregunta


No hay nada que impida que su bucle reverse_iterator también use el índice como se describe en muchas otras respuestas. De esta forma, puede usar el iterador o índice según sea necesario en la parte // do the work , por un costo adicional mínimo.

size_t index = v.size() - 1; for(std::vector<SomeT>::reverse_iterator rit = v.rbegin(); rit != v.rend(); ++rit, --index) { // do the work }

Aunque tengo curiosidad por saber para qué necesitas el índice. Acceder a v[index] es lo mismo que acceder a *rit .


Pruebe hacer mientras:

std::vector<Type> v; // Some code if(v.size() > 0) { unsigned int i = v.size() - 1; do { // Your stuff } while(i-- > 0); }


condición de bucle i != std::numeric_limits<unsigned>::max() ... o use UINT_MAX si cree que es verboso. o de otra manera:
for(unsigned j=0, end=v.size(), i=end-1; j<end; --i, ++j)
o
for(unsigned end=v.size(), i=end-1; (end-i)<end; --i)


para ser estéticamente agradable! ;)

for(unsigned i = v.size() - 1; v.size() > i; --i)


Preferiría la variante inversa del iterador, porque aún es fácil de interpretar y permite evitar los errores relacionados con el índice.

A veces, simplemente puede usar BOOST_REVERSE_FOREACH , lo que haría que su código se vea de la siguiente manera:

reverse_foreach (int value, vector) { do_something_with_the_value; }

En realidad, siempre puedes usar declaraciones foreach para este tipo de bucles, pero luego se vuelven poco evidentes:

size_t i = 0; foreach (int value, vector) { do_something; ++i; }


for (it = v.end()-1; it != v.begin()-1; --it) { }

El operador "goes to" definitivamente se mete con la cabeza.