over index for findindex c++ c++11 foreach

index - Obtener índice en bucle foreach C++ 11



iterate map c++ 11 (3)

¿Qué pasa con una solución simple como:

int counter=0; for (auto &val: container) { makeStuff(val, counter); counter++; }

Podría hacer un poco más "difícil" agregar código después del contador agregando un alcance:

int counter=0; for (auto &val: container) {{ makeStuff(val, counter); }counter++;}

Como @ graham.reeds señaló, lo normal for bucle también es una solución, que podría ser tan rápida:

int counter=0; for (auto it=container.begin(); it!=container.end(); ++it, ++counter) { makeStuff(val, counter); }

Y por último, una forma alternativa utilizando algoritmo:

int counter = 0; std::for_each(container.begin(), container.end(), [&counter](int &val){ makeStuff(val, counter++); });

Nota: el orden entre el bucle de rango y el bucle normal está garantizado por el estándar 6.5.4. Lo que significa que el contador puede ser coherente con la posición en el contenedor.

¿Existe una manera conveniente de obtener el índice de la entrada del contenedor actual en un bucle foreach de C ++ 11, como enumerate en python:

for idx, obj in enumerate(container): pass

Podría imaginar un iterador que también puede devolver el índice o similar.

Por supuesto, podría tener un contador, pero a menudo los iteradores no dan garantías del orden que iteran en un contenedor.


Si necesitas el índice entonces un tradicional para funciona perfectamente bien.

for (int idx=0; idx<num; ++idx) { // do stuff }


Una buena implementación de la característica que se le solicita se puede encontrar aquí:

https://github.com/ignatz/pythonic

La idea subyacente es que usted construye una estructura de envoltorio con un iterador personalizado que realiza el conteo. A continuación se muestra una implementación ejemplar muy mínima para ilustrar la idea:

#include <iostream> #include <vector> #include <tuple> // Wrapper class template <typename T> class enumerate_impl { public: // The return value of the operator* of the iterator, this // is what you will get inside of the for loop struct item { size_t index; typename T::value_type & item; }; typedef item value_type; // Custom iterator with minimal interface struct iterator { iterator(typename T::iterator _it, size_t counter=0) : it(_it), counter(counter) {} iterator operator++() { return iterator(++it, ++counter); } bool operator!=(iterator other) { return it != other.it; } typename T::iterator::value_type item() { return *it; } value_type operator*() { return value_type{counter, *it}; } size_t index() { return counter; } private: typename T::iterator it; size_t counter; }; enumerate_impl(T & t) : container(t) {} iterator begin() { return iterator(container.begin()); } iterator end() { return iterator(container.end()); } private: T & container; }; // A templated free function allows you to create the wrapper class // conveniently template <typename T> enumerate_impl<T> enumerate(T & t) { return enumerate_impl<T>(t); } int main() { std::vector<int> data = {523, 1, 3}; for (auto x : enumerate(data)) { std::cout << x.index << ": " << x.item << std::endl; } }