error: pasar xxx como ‘este’ argumento de xxx descarta los calificadores

#include  #include  using namespace std; class StudentT { public: int id; string name; public: StudentT(int _id, string _name) : id(_id), name(_name) { } int getId() { return id; } string getName() { return name; } }; inline bool operator< (StudentT s1, StudentT s2) { return s1.getId() < s2.getId(); } int main() { set st; StudentT s1(0, "Tom"); StudentT s2(1, "Tim"); st.insert(s1); st.insert(s2); set :: iterator itr; for (itr = st.begin(); itr != st.end(); itr++) { cout <getId() << " " <getName() << endl; } return 0; } 

En línea:

 cout <getId() << " " <getName() << endl; 

Da un error que:

../main.cpp:35: error: al pasar ‘const StudentT’ como ‘este’ argumento de ‘int StudentT :: getId ()’ descarta los calificadores

../main.cpp:35: error: al pasar ‘const StudentT’ como ‘este’ argumento de ‘std :: string StudentT :: getName ()’ descarta los calificadores

¿Qué pasa con este código? ¡Gracias!

Los objetos en std::set se almacenan como const StudentT . Entonces, cuando intentas llamar a getId() con el objeto const el comstackdor detecta un problema, principalmente llamas a una función miembro no const en el objeto const que no está permitido porque las funciones miembro no constantes NO HACEN PROMESA para no modificar el objeto; por lo que el comstackdor getId() seguridad que getId() podría intentar modificar el objeto pero, al mismo tiempo, también nota que el objeto es const; por lo que cualquier bash de modificar el objeto const debería ser un error. Por lo tanto, el comstackdor genera un mensaje de error.

La solución es simple: hacer las funciones const como:

 int getId() const { return id; } string getName() const { return name; } 

Esto es necesario porque ahora puedes llamar a getId() y getName() en objetos const como:

 void f(const StudentT & s) { cout < < s.getId(); //now okay, but error with your versions cout << s.getName(); //now okay, but error with your versions } 

Como nota al margen, debe implementar operator< as:

 inline bool operator< (const StudentT & s1, const StudentT & s2) { return s1.getId() < s2.getId(); } 

Los parámetros de nota ahora son referencia const .

Las funciones miembro que no modifican la instancia de la clase deben declararse como const :

 int getId() const { return id; } string getName() const { return name; } 

Cada vez que vea “descartables calificadores”, se trata de const o volatile .

En realidad, el estándar de C ++ (es decir, el borrador de C ++ 0x ) dice (tnx a @Xeo y @Ben Voigt por señalarme eso):

23.2.4 Contenedores asociativos
5 Para set y multiset, el tipo de valor es el mismo que el tipo de clave. Para mapa y multimapa es igual a par. Las claves en un contenedor asociativo son inmutables.
6 iterador de un contenedor asociativo es de la categoría de iterador bidireccional. Para los contenedores asociativos donde el tipo de valor es el mismo que el tipo de clave, tanto iterator como const_iterator son iteradores constantes. No se especifica si iterator y const_iterator son del mismo tipo o no.

Entonces, la implementación de VC ++ 2008 Dinkumware es defectuosa.


Respuesta anterior:

Obtuviste ese error porque en ciertas implementaciones de std lib el set::iterator es el mismo que set::const_iterator .

Por ejemplo, libstdc ++ (incluido con g ++) lo tiene (ver aquí el código fuente completo):

 typedef typename _Rep_type::const_iterator iterator; typedef typename _Rep_type::const_iterator const_iterator; 

Y en los documentos de SGI dice:

 iterator Container Iterator used to iterate through a set. const_iterator Container Const iterator used to iterate through a set. (Iterator and const_iterator are the same type.) 

Por otro lado, VC ++ 2008 Express comstack su código sin quejarse de que está llamando a métodos no const en set::iterator s.

Déjenme dar un ejemplo más detallado. En cuanto a la siguiente estructura:

 struct Count{ uint32_t c; Count(uint32_t i=0):c(i){} uint32_t getCount(){ return c; } uint32_t add(const Count& count){ uint32_t total = c + count.getCount(); return total; } }; 

enter image description here

Como verá lo anterior, el IDE (CLion) dará sugerencias. La función Non-const function 'getCount' is called on the const object . En el método add count se declara como objeto const, pero el método getCount no es método const, por lo que count.getCount() puede cambiar los miembros en count .

Comstack el error como a continuación (mensaje principal en mi comstackdor):

 error: passing 'const xy_stl::Count' as 'this' argument discards qualifiers [-fpermissive] 

Para resolver el problema anterior, puede:

  1. cambie el método uint32_t getCount(){...} a uint32_t getCount() const {...} . Entonces count.getCount() no cambiará los miembros en count .

o

  1. cambie uint32_t add(const Count& count){...} para uint32_t add(Count& count){...} . Así que no importa cambiar miembros en él.

En cuanto a su problema, los objetos en el conjunto std :: se almacenan como const StudentT, pero el método getId y getName no son const, por lo que se getId el error anterior.

También puede ver esta pregunta. ¿El significado de ‘const’ es el último en una statement de función de una clase? para más detalles.