erreur: passer xxx comme ‘cet’ argument de xxx supprime les qualificatifs

#include  #include  using namespace std; class StudentT { public: int id; ssortingng name; public: StudentT(int _id, ssortingng _name) : id(_id), name(_name) { } int getId() { return id; } ssortingng 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 ligne:

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

Cela donne une erreur que:

../main.cpp:35: erreur: passer ‘const StudentT’ comme ‘cet’ argument de ‘int StudentT :: getId ()’ supprime les qualificateurs

../main.cpp:35: erreur: passer ‘const StudentT’ comme ‘cet’ argument de ‘std :: ssortingng StudentT :: getName ()’ supprime les qualificateurs

Quel est le problème avec ce code? Je vous remercie!

Les objects dans le std::set sont stockés en tant que const StudentT . Donc, quand vous essayez d’appeler getId() avec l’object const , le compilateur détecte un problème, principalement vous appelez une fonction membre non-const sur un object const qui n’est pas autorisé car les fonctions membres non-const ne promettent pas de modifier le object; Ainsi, le compilateur va supposer que getId() peut tenter de modifier l’object mais en même temps, il remarque également que l’object est const. donc toute tentative de modifier l’object const devrait être une erreur. Par conséquent, le compilateur génère un message d’erreur.

La solution est simple: rendre les fonctions const comme:

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

Cela est nécessaire car maintenant vous pouvez appeler getId() et getName() sur des objects const comme:

 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 } 

En tant que sidenote, vous devez implémenter operator< as:

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

Les parameters de note sont maintenant référence const .

Les fonctions membres qui ne modifient pas l’instance de classe doivent être déclarées comme const :

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

A chaque fois que vous voyez “éliminer les qualificatifs”, il est question de const ou de volatile .

En fait, le standard C ++ (c.-à-d . Le brouillon C ++ 0x ) dit (tnx à @Xeo & @Ben Voigt pour me le signaler):

23.2.4 Conteneurs associatifs
5 Pour set et multiset, le type de valeur est le même que le type de clé. Pour la carte et le multimap, il est égal à la paire. Les clés d’un conteneur associatif sont immuables.
6 iterator d’un conteneur associatif est de la catégorie iterator bidirectionnel. Pour les conteneurs associatifs où le type de valeur est le même que le type de clé, iterator et const_iterator sont des iterators constants. Il n’est pas spécifié si l’iterator et const_iterator sont du même type ou non.

L’implémentation de VC ++ 2008 Dinkumware est donc défectueuse.


Vieille réponse:

Vous avez cette erreur car dans certaines implémentations de la librairie std, set::iterator est identique à set::const_iterator .

Par exemple, libstdc ++ (fourni avec g ++) le contient (voir ici le code source complet):

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

Et dans les documents de SGI, il est écrit:

 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.) 

Par contre, VC ++ 2008 Express comstack votre code sans se plaindre que vous appelez des méthodes non const sur set::iterator s.

Permettez-moi de donner un exemple plus détaillé. En ce qui concerne la structure ci-dessous:

 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; } }; 

entrer la description de l'image ici

Comme vous le voyez ci-dessus, l’IDE (CLion) donnera des conseils Non-const function 'getCount' is called on the const object . Dans la méthode, add count est déclaré en tant qu’object const, mais la méthode getCount n’est pas une méthode const, alors count.getCount() peut modifier les membres de count .

Erreur de compilation comme ci-dessous (message principal dans mon compilateur):

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

Pour résoudre le problème ci-dessus, vous pouvez:

  1. changez la méthode uint32_t getCount(){...} en uint32_t getCount() const {...} . Donc count.getCount() ne changera pas les membres de count .

ou

  1. changez uint32_t add(const Count& count){...} en uint32_t add(Count& count){...} . Donc, ne vous souciez pas de changer de membre.

En ce qui concerne votre problème, les objects dans le std :: set sont stockés sous la forme const StudentT, mais la méthode getId et getName ne sont pas const, vous donnez donc l’erreur ci-dessus.

Vous pouvez également voir cette question Signification de ‘const’ last dans une déclaration de fonction d’une classe? pour plus de détails.