#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 'este' 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é tiene de malo este código? ¡Gracias!

volatileRespuestas:
Los objetos en el
std::setse almacenan comoconst StudentT. Entonces, cuando intentas llamargetId()con elconstobjeto, el compilador detecta un problema, principalmente estás llamando a una función miembro no constante en el objeto constante que no está permitida porque las funciones miembro no constantes NO PROMETEN NO modificar el objeto; así que el compilador hará una suposición segura quegetId()podría intentar modificar el objeto pero al mismo tiempo, también se da cuenta de que el objeto es constante; entonces 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 las funciones constantes como:
Esto es necesario porque ahora puede llamar
getId()ygetName()en objetos const como:Como nota al margen, debe implementar
operator<como:Los parámetros de nota ahora son de
constreferencia.fuente
const StudentT & s1, const StudentT & s2?constdebido a que la función no necesita modificar el objeto, por lo que seconstaplica en tiempo de compilación.Las funciones miembro que no modifican la instancia de clase deben declararse como
const:Cada vez que ves "calificadores de descarte", se trata de
constovolatile.fuente
constviene el aquí, pero sospecho quesetestá devolviendo una referencia constante del iterador para evitar que la instancia cambie y, por lo tanto, invalide el conjunto.foo obj;aconst foo obj;una vez y vea qué sucede. O pasar unaconstreferencia a afoo.setse cambian los elementos en a , el orden se puede alterar y el conjunto ya no es válido. En amap, solo la clave esconst. En aset, todo el objeto es realmente la clave.f()en mi respuesta.En realidad, el estándar C ++ (es decir, C ++ 0x draft ) dice (tnx a @Xeo y @Ben Voigt por señalarme eso):
Entonces, la implementación de VC ++ 2008 Dinkumware es defectuosa.
Vieja respuesta:
Obtuviste ese error porque en ciertas implementaciones de std lib
set::iteratores igual queset::const_iterator.Por ejemplo, libstdc ++ (incluido con g ++) lo tiene (consulte aquí el código fuente completo):
Y en los documentos de SGI dice:
Por otro lado, VC ++ 2008 Express compila su código sin quejarse de que está llamando a métodos no constantes en
set::iterators.fuente
Permítanme dar un ejemplo más detallado. En cuanto a la siguiente estructura:
Como ve lo anterior, el IDE (CLion) le dará consejos
Non-const function 'getCount' is called on the const object. En el métodoaddcountse declara como objeto const, pero el métodogetCountno es const, por lo quecount.getCount()puede cambiar los miembros encount.Error de compilación como se muestra a continuación (mensaje principal en mi compilador):
Para resolver el problema anterior, puede:
uint32_t getCount(){...}auint32_t getCount() const {...}. Entoncescount.getCount()no cambiará a los miembroscount.o
uint32_t add(const Count& count){...}auint32_t add(Count& count){...}. Así quecountno me importa cambiar miembros en él.En cuanto a su problema, los objetos en std :: set se almacenan como const StudentT, pero son el método
getIdygetNameno son const, por lo que da el error anterior.También puede ver esta pregunta ¿Qué significa 'const' último en una declaración de función de una clase? para más detalles.
fuente