2011-02-03 27 views
36

Tengo un vector de Estudiante que tiene un nombre de campo.¿Cómo iterar sobre un vector constante?

Quiero iterar sobre el vector.

void print(const vector<Student>& students) 
    { 
    vector<Student>::iterator it; 
    for(it = students.begin(); it < students.end(); it++) 
     { 
      cout << it->name << endl; 
     } 
    } 

Esto es aparentemente ilegal en C++.

Por favor ayuda.

+2

favor, lea sobre el prefijo de frente operador de incremento postfix. 'it ++' debe ser '++ it', y' it ++ 'es necesario en casos excepcionales (es decir, al borrar mientras se itera). –

+2

Es bastante obvio cuál es el problema en este caso. Sin embargo, en el futuro debe incluir en su pregunta el mensaje de error exacto que le está dando el compilador. –

Respuesta

53

Has dos (tres en 11 C++) opciones: const_iterator s e índices (+ "de rango-para" en C++ 11)

void func(const std::vector<type>& vec) { 
    std::vector<type>::const_iterator iter; 
    for (iter = vec.begin(); iter != vec.end(); ++iter) 
    // do something with *iter 

    /* or 
    for (size_t index = 0; index != vec.size(); ++index) 
    // do something with vec[index] 

    // as of C++11 
    for (const auto& item: vec) 
    // do something with item 
    */ 
} 

Usted debe preferir el uso de != vez de < con iteradores; este último no funciona con todos los iteradores, el primero lo hará. En el primer caso se puede incluso hacer el código más genérico (de modo que incluso se podría cambiar el tipo de contenedor sin tocar el bucle)

template<typename Container> 
void func(const Container& container) { 
    typename Container::const_iterator iter; 
    for (iter = container.begin(); iter != container.end(); ++iter) 
    // work with *iter 
} 
+0

Soy nuevo en iteradores. ¿Puedes decirme qué iteradores no me gustan? = ¿Y por qué? – unj2

+4

@kunjaan: Solo los iteradores de acceso aleatorio admiten el orden ('<'), otros no. Por ejemplo, std :: list tiene iteradores bidireccionales, que solo se pueden comparar por igualdad. –

16

Use const_iterator en su lugar. Un iterator permite la modificación del vector, por lo que no puede obtener uno de un contenedor const.

Además, la forma idiomática de escribir este ciclo utiliza it != students.end() en lugar de < (aunque esto debería funcionar en un vector).

+2

... pero si alguna vez decide cambiar para usar una 'list' o algo similar, su código no funcionará. Entonces usa la forma '! ='. –

2
void print(const vector<Student>& students) 
    { 
    vector<Student>::const_iterator it; // const_iterator 
    for(it = students.begin(); it != students.end(); it++) 
     { 
      cout << it->name << endl; 
     } 
    } 
3

En lugar de vector<Student>::iterator, utilice vector<Student>::const_iterator.

2
void print(const vector<Student>& students) 
    { 
    for(auto it = students.begin(); it != students.end(); ++it) 
     { 
      cout << it->name << endl; 
     } 
    } 
+1

esta pregunta no está etiquetada C++ 0x – smerlin

+2

Pero esto es bueno para recordarnos acerca de esa característica, tal vez nos anima a cambiar a C++ 11. +1 – Offirmo

1

C++ 11 estilo:

void print(const vector<Student>& students) { 
    for(auto const& student : students) { 
      cout << student.name << endl; 
    } 
}