2012-01-06 4 views
8

En mi archivo de cabecera, he incluido el archivo std :: map y uso el espacio de nombre apropiado.
Uno de los miembros de mi es:Error de compilación utilizando los iteradores de mapa

map<unsigned int, double> pT_Spam; 

Y en mi archivo .cpp que intento hacer algo que he estado haciendo con frecuencia desde hace algún tiempo:

for(map<unsigned int, double>::iterator it=pT_Spam.begin() ; it!=pT_Spam.end() ; it++) {/*code*/} 

Lo anterior siquiera se menciona en uno de los ejemplos de usar std :: map en cplusplus.com. A pesar de que he hecho más o menos lo mismo en otras partes del código que no causan errores de compilación, en esta línea particular me sale el siguiente error de Cygwin:

error: conversion from `std::_Rb_tree_const_iterator<std::pair<const unsigned int, double> >' to non-scalar type `std::_Rb_tree_iterator<std::pair<const unsigned int, double> >' requested 

que parece bastante extraño. ¿Alguna idea de lo que podría estar mal? (Mi cabecera es, por supuesto, incluido en mi .cpp)

+0

Se queja de que el iterador devuelto por begin() es un const_iterator, pero lo está asignando a un iterador. Pero no estoy seguro de por qué, esto también me parece bien. ¿Qué compilador es esto? – Joe

+0

[begin()] (http://cplusplus.com/reference/stl/map/begin/) parece ser capaz de devolver iteradores no const también. Uso g ++ de Cygwin en Windows. – jathanasiou

Respuesta

16

Parecería que en el ámbito este lazo existe, el mapa es const. Por ejemplo, ¿el bucle en un método de clase se declara const, como tal?

void method() const // const method 
{ 
    // Do stuff. 
} 

o pasado como un argumento const, como esto?

void function(const map<unsigned int, double>& pT_Spam) 
{ 
    // Do stuff. 
} 

Si es así, usted debe usar iteradores const:

for(map<unsigned int, double>::const_iterator it=pT_Spam.begin() ; it!=pT_Spam.end() ; it++) 
{ 
    /*code*/ 
} 

O, si usted está usando C++ 11, entonces debería usar la palabra clave auto:

for(auto it=pT_Spam.begin() ; it!=pT_Spam.end(); it++) 
{ 
    /*code*/ 
} 

Dado que en el caso que ha mostrado debe usar iteradores de const, no puede usarlos para modificar el mapa o los datos dentro de él. Eso es const corrección, y es algo bueno :).

+2

-.25 para usar auto de una manera que mata a los gatitos. ;) –

+1

Una alternativa es marcar al miembro como ['mutable'] (http://www.highprogrammer.com/alan/rants/mutable.html). Pero no le digas a nadie que te dije eso :-) –

+0

El método que ejecuta el ciclo es de hecho const, y eso me hace entender por qué el mapa también está en su alcance. Teniendo en cuenta que no necesito editarlo en este método, los iteradores de comandos parecen responder. – jathanasiou

2

Es necesario utilizar const_iterators para los mapas, por lo que debe ser:

for(map<unsigned int, double>::const_iterator it = \\and so on 

Editar: Como se ha señalado lo anterior es correcto, pero para completamente incorrecto razones (los mapas tienen iteradores no const. ¿Qué estaba pensando exactamente? No lo sé). Lo más probable es que su mapa se defina como const (como se señala en otra respuesta).

+1

¿No causará problemas al modificar su valor (es ++)? Además, he estado usando iteradores regulares para bucles similares hasta ahora y nunca he tenido problemas. – jathanasiou

+2

Um, ¿qué? map tiene iteradores no const. –

+1

@JohnAthanasiou: ¡Un const-iterator mutable no es lo mismo que un iterador const non-const! Piensa 'T const *' vs 'T * const'. –

3

Bueno, el error dice que estás intentando lanzar un const_iterator a un iterador. Usted dice que pT_Spam es miembro. ¿Es un miembro de un objeto const? Si es así, begin() y end() devolverán const_iterators.

+0

No estoy seguro de ser honesto, es un miembro privado declarado de mi clase 'nbclassifier', mientras que el método que realiza el ciclo también es miembro de esa clase. – jathanasiou

+0

Una alternativa es marcar al miembro como ['mutable'] (http://www.highprogrammer.com/alan/rants/mutable.html). Pero no le digas a nadie que te dije eso :-) –

+0

Const está llegando a algún lado. Si la variable miembro no se declara const, y si el método no se declara const, entonces tal vez se llame al método sobre un objeto const (lo que haría que la variable miembro sea implícitamente const). ¿El error del compilador viene con una pila de llamadas? EDITAR: espera, tendría que ser un método const si se está llamando a un objeto const. –

1

para (mapa :: iterador it = pT_Spam.begin (!), Que pT_Spam.end =(); se ++)

chage a

para (mapa :: const_iterator it = pT_Spam. begin(); it! = pT_Spam.end(); it ++)

Como apunta a un valor constante, el iterador también debe ser de tipo const.

Cuestiones relacionadas