c++ - errore: passare xxx come argomento "this" di xxx elimina i qualificatori


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

In linea:

cout << itr->getId() << " " << itr->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!



Answers



Gli oggetti in std::set sono memorizzati come const StudentT . Quindi, quando provi a chiamare getId() con l'oggetto const , il compilatore rileva un problema, ovvero stai chiamando una funzione membro non const su oggetto const che non è consentita perché le funzioni membro non const fanno NESSUNA PROMESSIONE di non modificare il oggetto; quindi il compilatore farà un assunto sicuro che getId() potrebbe tentare di modificare l'oggetto ma allo stesso tempo, si accorge anche che l'oggetto è const; quindi qualsiasi tentativo di modificare l'oggetto 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 classe 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.










Tags