online ejemplos descargar definicion caracteristicas c++

c++ - ejemplos - error: pasar xxx como ''este'' argumento de xxx descarta los calificadores



c++ online (4)

Déjame 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; } };

Como ve lo anterior, el IDE (CLion) le dará sugerencias 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 un método const, por lo que count.getCount() puede cambiar los miembros del count .

Error de compilación de la siguiente manera (mensaje central en mi compilador):

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

Para resolver el problema anterior, puedes:

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

o

  1. cambie uint32_t add(const Count& count){...} a uint32_t add(Count& count){...} . Así que a la count no le importa cambiar miembros en ella.

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

También puede ver esta pregunta ¿ Significado de ''const'' último en una declaración de función de una clase? para más detalles.

#include <iostream> #include <set> 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<StudentT> st; StudentT s1(0, "Tom"); StudentT s2(1, "Tim"); st.insert(s1); st.insert(s2); set<StudentT> :: iterator itr; for (itr = st.begin(); itr != st.end(); itr++) { cout << itr->getId() << " " << itr->getName() << endl; } return 0; }

En línea:

cout << itr->getId() << " " << itr->getName() << endl;

Da un error que:

../main.cpp:35: error: pasar ''const StudentT'' como ''this'' argumento de ''int StudentT :: getId ()'' descarta los calificadores

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

¿Qué hay de malo con este código? ¡Gracias!


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

23.2.4 Contenedores asociativos
5 Para set y multiset el tipo de valor es el mismo que el tipo de clave. Para map y multimap es igual a par. Las claves en un contenedor asociativo son inmutables.
6 iterador de un contenedor asociativo es de la categoría iterador bidireccional. Para 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 iterador y const_iterator son o no del mismo tipo.

Así que la implementación de Dinkumware VC ++ 2008 es defectuosa.

Respuesta antigua:

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

Por ejemplo, libstdc ++ (enviado con g ++) lo tiene (consulte here el código fuente completo):

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

Y en los docs la 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 compila su código sin quejarse de que está llamando métodos no constantes en set::iterator s.


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

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

Cada vez que vea "descarte calificadores", se trata de const o volatile .


Los objetos en el std::set se almacenan como const StudentT . Entonces, cuando intenta llamar a getId() con el objeto const el compilador detecta un problema, principalmente está llamando a una función miembro no constante en el objeto const, que no está permitido porque las funciones miembro no const no hacen NINGUNA PROMESA de no modificar el objeto; así que el compilador va a hacer una suposición segura de que getId() podría intentar modificar el objeto, pero al mismo tiempo, también se da cuenta de que el objeto es constante; por lo que cualquier intento de modificar el objeto const debería ser un error. Por lo tanto, el compilador genera un mensaje de error.

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

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

Esto es necesario porque ahora puede 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 el operator< como:

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

Los parámetros de la nota son ahora const referencia.