Iteración sobre std::vector:variable de índice sin firmar vs firmada

Iteración sobre std::vector:variable de índice sin firmar vs firmada

Para iterar hacia atrás, vea esta respuesta.

Iterar hacia adelante es casi idéntico. Simplemente cambie los iteradores / decremento de intercambio por incremento. Deberías preferir los iteradores. Algunas personas te dicen que uses std::size_t como el tipo de variable de índice. Sin embargo, eso no es portátil. Utilice siempre el size_type typedef del contenedor (si bien podría salirse con la suya con solo una conversión en el caso de iteración hacia adelante, en realidad podría salir mal en el caso de iteración hacia atrás cuando se usa std::size_t , en caso std::size_t es más ancho que el typedef de size_type ):

Usando estándar::vector

Uso de iteradores

for(std::vector<T>::iterator it = v.begin(); it != v.end(); ++it) {
    /* std::cout << *it; ... */
}

Es importante usar siempre la forma de incremento de prefijo para los iteradores cuyas definiciones no conoce. Eso asegurará que su código se ejecute de la manera más genérica posible.

Uso del rango C++11

for(auto const& value: a) {
     /* std::cout << value; ... */

Uso de índices

for(std::vector<int>::size_type i = 0; i != v.size(); i++) {
    /* std::cout << v[i]; ... */
}

Uso de matrices

Uso de iteradores

for(element_type* it = a; it != (a + (sizeof a / sizeof *a)); it++) {
    /* std::cout << *it; ... */
}

Uso del rango C++11

for(auto const& value: a) {
     /* std::cout << value; ... */

Uso de índices

for(std::size_t i = 0; i != (sizeof a / sizeof *a); i++) {
    /* std::cout << a[i]; ... */
}

Lea en la respuesta de iteración hacia atrás qué problema tiene el sizeof Sin embargo, el enfoque puede ceder.


Pasaron cuatro años, Google me dio esta respuesta. Con el estándar C++11 (también conocido como C++0x ) en realidad hay una nueva forma agradable de hacer esto (al precio de romper la compatibilidad con versiones anteriores):el nuevo auto palabra clave. Le ahorra el dolor de tener que especificar explícitamente el tipo de iterador a usar (repitiendo el tipo de vector nuevamente), cuando es obvio (para el compilador), qué tipo usar. Con v siendo tu vector , puedes hacer algo como esto:

for ( auto i = v.begin(); i != v.end(); i++ ) {
    std::cout << *i << std::endl;
}

C++11 va aún más allá y le brinda una sintaxis especial para iterar sobre colecciones como vectores. Elimina la necesidad de escribir cosas que son siempre las mismas:

for ( auto &i : v ) {
    std::cout << i << std::endl;
}

Para verlo en un programa de trabajo, cree un archivo auto.cpp :

#include <vector>
#include <iostream>

int main(void) {
    std::vector<int> v = std::vector<int>();
    v.push_back(17);
    v.push_back(12);
    v.push_back(23);
    v.push_back(42);
    for ( auto &i : v ) {
        std::cout << i << std::endl;
    }
    return 0;
}

Al momento de escribir esto, cuando compilas esto con g++ , normalmente necesita configurarlo para que funcione con el nuevo estándar dando una marca adicional:

g++ -std=c++0x -o auto auto.cpp

Ahora puede ejecutar el ejemplo:

$ ./auto
17
12
23
42

Tenga en cuenta que las instrucciones de compilación y ejecución son específicas para gnu c++ compilador en Linux , el programa debe ser independiente de la plataforma (y del compilador).


En el caso específico de su ejemplo, usaría los algoritmos STL para lograr esto.

#include <numeric> 

sum = std::accumulate( polygon.begin(), polygon.end(), 0 );

Para un caso más general, pero aún bastante simple, iría con:

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>

using namespace boost::lambda;
std::for_each( polygon.begin(), polygon.end(), sum += _1 );