#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 ligne:
cout << itr->getId() << " " << itr->getName() << endl;
Cela donne une erreur qui:
../main.cpp:35: erreur: passer 'const StudentT' comme 'cet' argument de 'int StudentT :: getId ()' élimine les qualificatifs
../main.cpp:35: erreur: passer 'const StudentT' comme 'cet' argument de 'std :: string StudentT :: getName ()' supprime les qualificatifs
Quel est le problème avec ce code? Je vous remercie!
volatile
Réponses:
Les objets du
std::set
sont stockés sousconst StudentT
. Ainsi, lorsque vous essayez d'appelergetId()
avec l'const
objet, le compilateur détecte un problème, vous appelez principalement une fonction membre non const sur un objet const qui n'est pas autorisé car les fonctions membres non const ne font AUCUNE PROMESSE de ne pas modifier l'objet; donc le compilateur va faire une hypothèse sûre quigetId()
pourrait tenter de modifier l'objet mais en même temps, il remarque également que l'objet est const; toute tentative de modification de l'objet const doit donc être une erreur. Par conséquent, le compilateur génère un message d'erreur.La solution est simple: rendre les fonctions constantes comme:
Ceci est nécessaire car vous pouvez maintenant appeler
getId()
etgetName()
sur des objets const comme:En tant que sidenote, vous devez implémenter en
operator<
tant que:Les paramètres de note sont désormais des
const
références.la source
const StudentT & s1, const StudentT & s2
?const
parce que la fonction n'a pas besoin de modifier l'objet, donc elleconst
applique cela au moment de la compilation.Les fonctions membres qui ne modifient pas l'instance de classe doivent être déclarées comme
const
:Chaque fois que vous voyez "défausse les qualificatifs", il s'agit de
const
ouvolatile
.la source
const
vient d'ici, mais je soupçonne que leset
retourne une référence const de l'itérateur pour empêcher l'instance de changer et ainsi invalider l'ensemble.foo obj;
enconst foo obj;
une fois et voyez ce qui se passe. Ou passez uneconst
référence à afoo
.set
sont modifiés, l'ordre peut être bouleversé, puis l'ensemble n'est plus valide. Dans unmap
, seule la clé estconst
. Dans unset
, tout l'objet est vraiment la clé.f()
dans ma réponse.En fait, la norme C ++ (c'est-à-dire le projet C ++ 0x ) dit (tnx à @Xeo & @Ben Voigt pour me l'avoir signalé):
La mise en œuvre de VC ++ 2008 Dinkumware est donc défectueuse.
Ancienne réponse:
Vous avez cette erreur , car dans certaines implémentations de la lib std l'
set::iterator
est le même queset::const_iterator
.Par exemple, libstdc ++ (livré avec g ++) l'a (voir ici pour le code source complet):
Et dans les documents de SGI, il indique:
D'autre part, VC ++ 2008 Express compile votre code sans se plaindre d'appeler des méthodes non const sur
set::iterator
s.la source
Permettez-moi de donner un exemple plus détaillé. Quant à la structure ci-dessous:
Comme vous le voyez ci-dessus, l'IDE (CLion), vous donnera des conseils
Non-const function 'getCount' is called on the const object
. Dans la méthodeadd
count
est déclarée comme objet const, mais la méthodegetCount
n'est pas une méthode const, donccount.getCount()
peut changer les membres danscount
.Erreur de compilation comme ci-dessous (message principal dans mon compilateur):
Pour résoudre le problème ci-dessus, vous pouvez:
uint32_t getCount(){...}
enuint32_t getCount() const {...}
.count.getCount()
Ne changera donc pas les membrescount
.ou
uint32_t add(const Count& count){...}
pouruint32_t add(Count& count){...}
. Donc,count
ne vous souciez pas de changer de membre.Quant à votre problème, les objets dans le std :: set sont stockés en tant que const StudentT, mais la méthode
getId
etgetName
ne sont pas const, vous donnez donc l'erreur ci-dessus.Vous pouvez également voir cette question Signification de «const» en dernier dans une déclaration de fonction d'une classe? pour plus de détails.
la source