errore: passare xxx come argomento “this” di xxx elimina i qualificatori

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

In linea:

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

Dà un errore che:

../main.cpp:35: errore: passare ‘const StudentT’ come ‘this’ argomento di ‘StudentT :: getId ()’ ignora i qualificatori

../main.cpp:35: errore: passare ‘const StudentT’ come ‘this’ argomento di ‘std :: string StudentT :: getName ()’ elimina i qualificatori

Cosa c’è di sbagliato con questo codice? Grazie!

Gli oggetti in std::set sono memorizzati come const StudentT . Quindi, quando provi a chiamare getId() con l’object const , il compilatore rileva un problema, principalmente stai chiamando una funzione membro non const su object const che non è consentita perché le funzioni membro non const fanno NESSUNA PROMESSA di non modificare il object; quindi il compilatore farà un assunto sicuro che getId() potrebbe tentare di modificare l’object ma allo stesso tempo, si accorge anche che l’object è const; quindi qualsiasi tentativo di modificare l’object const dovrebbe essere un errore. Quindi il compilatore genera un messaggio di errore.

La soluzione è semplice: rendere le funzioni const come:

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

Questo è necessario perché ora puoi chiamare getId() e getName() su oggetti const come:

 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 } 

Come sidenote, dovresti implementare l' operator< come:

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

I parametri di nota sono ora riferimento const .

Le funzioni membro che non modificano l’istanza della class devono essere dichiarate come const :

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

Ogni volta che vedi “qualificazioni degli scarti”, si tratta di const o volatile .

In realtà lo standard C ++ (cioè C ++ 0x draft ) dice (tnx a @Xeo & @Ben Voigt per averlo indicato):

23.2.4 Contenitori associativi
5 Per set e multiset il tipo di valore è uguale al tipo di chiave. Per mappa e multimappa è uguale alla coppia. Le chiavi in ​​un contenitore associativo sono immutabili.
6 iteratore di un contenitore associativo appartiene alla categoria iteratore bidirezionale. Per i contenitori associativi in ​​cui il tipo di valore è uguale al tipo di chiave, sia iteratore che const_iterator sono iteratori costanti. Non è specificato se iteratore e const_iterator siano o meno dello stesso tipo.

Quindi l’implementazione di Dinkumware VC ++ 2008 è difettosa.


Vecchia risposta:

Hai ottenuto questo errore perché in alcune implementazioni della lib std set::iterator è uguale a set::const_iterator .

Ad esempio, libstdc ++ (fornito con g ++) lo ha (vedi qui per l’intero codice sorgente):

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

E nei documenti SGI afferma:

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

D’altra parte VC ++ 2008 Express compila il tuo codice senza lamentarti del fatto che stai chiamando metodi non const su set::iterator s.

Facciamo un esempio più dettagliato. Per quanto riguarda la struttura sottostante:

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

inserisci la descrizione dell'immagine qui

Come si vede sopra, l’IDE (CLion) darà dei suggerimenti Non-const function 'getCount' is called on the const object . Nel metodo add count è dichiarato come const object, ma il metodo getCount non è un metodo const, quindi count.getCount() può cambiare i membri in count .

Compilare l’errore come di seguito (messaggio principale nel mio compilatore):

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

Per risolvere il problema precedente, puoi:

  1. cambia il metodo uint32_t getCount(){...} in uint32_t getCount() const {...} . Quindi count.getCount() non cambierà i membri nel count .

o

  1. cambia uint32_t add(const Count& count){...} a uint32_t add(Count& count){...} . Quindi count non si preoccupano di cambiare membri in esso.

Per quanto riguarda il tuo problema, gli oggetti di std :: set sono memorizzati come const Student, ma il metodo getId e getId non sono const, quindi dai l’errore sopra riportato.

Puoi anche vedere questa domanda Significato di ‘const’ ultimo in una dichiarazione di funzione di una class? per maggiori dettagli.