2009-03-26 8 views
14

C'è un motivo per cui il passaggio di un riferimento a una mappa STL come const causa la rottura dell'operatore []? Ottengo questo errore del compilatore (gcc 4.2) quando uso const:C++ const std :: il riferimento della mappa non riesce a compilare

error: no match for ‘operator[]’ in ‘map[name]’

Ecco il prototipo di funzione:

void func(const char ch, std::string &str, const std::map<std::string, std::string> &map); 

E, devo dire che non c'è nessun problema quando rimuovo il const parola chiave davanti a std :: mappa.

Se sono stato istruito correttamente, l'operatore [] inserirà effettivamente una nuova coppia nella mappa se non trova la chiave, il che spiegherebbe ovviamente perché ciò accade, ma non posso immaginare che questo sarebbe mai un comportamento accettabile.

Se esiste un metodo migliore, come utilizzare trovare anziché [], lo apprezzerei. Non riesco a trovare trovare a lavorare sia se ... Io ricevo const errori iteratori non corrispondenti.

Grazie.

risposta

26

Sì, non è possibile utilizzare operator[]. Utilizzare find, ma è da notare restituisce const_iterator invece di iterator:

std::map<std::string, std::string>::const_iterator it; 
it = map.find(name); 
if(it != map.end()) { 
    std::string const& data = it->second; 
    // ... 
} 

E 'come con i puntatori. Non è possibile assegnare int const* a int*. Allo stesso modo, non è possibile assegnare const_iterator a iterator.

6

Quando si utilizza l'operatore [], std :: map cerca l'elemento con la chiave specificata. Se non ne trova, lo crea. Da qui il problema con const.

Usa il metodo find e starai bene.

Puoi pubblicare un codice su come stai cercando di usare find()? Il modo giusto sarebbe:

if(map.find(name) != map.end()) 
{ 
    //... 
} 
2

Probabilmente perché non c'è nessun operatore const [] in std :: map. operator [] aggiungerà l'elemento che stai cercando se non lo trova. Pertanto, utilizzare il metodo find() se si desidera eseguire la ricerca senza la possibilità di aggiungere.

2

Per i tuoi "errori non corrispondenti iteratore const":

find() ha due overload:

 iterator find (const key_type& x); 
const_iterator find (const key_type& x) const; 

mio ipotesi è che stai ricevendo questo errore perché si sta facendo qualcosa di simile l'assegnazione di un iteratore non const (a sinistra) al risultato di una chiamata find() su una mappa const:

iterator<...> myIter /* non-const */ = myConstMap.find(...) 

Ciò comporterebbe un errore, anche se forse non quello che stai vedendo.

3

Se si utilizza C++ 11, std::map::at dovrebbe funzionare per voi.

Il motivo std::map::operator[] non funziona è che nel caso in cui la chiave che stai cercando non sia presente nella mappa, inserirà un nuovo elemento utilizzando la chiave fornita e restituirà un riferimento ad esso (Vedi il link per dettagli). Questo non è possibile su una const std :: map.

Il metodo 'at', tuttavia, genera un'eccezione se la chiave non esiste. Detto questo, è probabilmente una buona idea controllare l'esistenza della chiave usando il metodo std :: map :: find prima di tentare di accedere all'elemento usando il metodo 'at'.

Problemi correlati