Saltar al contenido

Obtener el índice en el ciclo foreach de C++ 11

Traemos la mejor solución que hemos encontrado on line. Nosotros deseamos que te sea de mucha ayuda y si puedes aportar cualquier detalle que nos pueda ayudar a crecer siente la libertad de hacerlo..

Solución:

Puede encontrar una buena implementación de la función que se le solicita aquí:

https://github.com/ignatz/pythonic

La idea detrás es que construyes una estructura contenedora con un iterador personalizado que hace el conteo. A continuación se muestra una implementación ejemplar mínima para ilustrar la idea:

#include 
#include 
#include 

// Wrapper class
template 
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_typecounter, *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 
enumerate_impl enumerate(T & t)

    return enumerate_impl(t);




int main()

    std::vector data = 523, 1, 3;
    for (auto x : enumerate(data))
    
        std::cout << x.index << ": " << x.item << std::endl;
    

¿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 señaló @graham.reeds, normal for loop 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 finalmente, una forma alternativa usando algoritmo:

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

Nota: el orden entre bucle de rango y 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.

Si tiene acceso a Boost, sus adaptadores de rango se pueden usar así:

using namespace boost::adaptors;

for (auto const& elem : container | indexed(0))

    std::cout << elem.index() << " - " << elem.value() << 'n';

Fuente (donde también hay otros ejemplos)

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *