Domanda

Il codice seguente dice che passare la mappa come const nel metodo operator[] scarta i qualificatori:

#include <iostream>
#include <map>
#include <string>

using namespace std;

class MapWrapper {
public:
    const int &get_value(const int &key) const {
        return _map[key];
    }

private:
    map<int, int> _map;
};

int main() {
    MapWrapper mw;
    cout << mw.get_value(42) << endl;
    return 0;
}

È a causa della possibile allocazione che si verifica sull'accesso alla mappa? Nessuna funzione con accesso alla mappa può essere dichiarata const?

MapWrapper.cpp:10: error: passing ‘const std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >’ as ‘this’ argument of ‘_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = int, _Tp = int, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, int> >]’ discards qualifiers

È stato utile?

Soluzione

std::map s operator [] non è dichiarato come const, e non può essere dovuto al suo comportamento:

  

T amp &; operator [] (const Key & amp; key)

     

Restituisce un riferimento al valore associato a una chiave equivalente a chiave, eseguendo l'inserimento se tale chiave non esiste già.

Di conseguenza, la funzione non può essere dichiarata operator[] e utilizzare la mappa find().

La funzione iterator ti consente di cerca una chiave senza modificare la mappa.

const_iterator restituisce un std::pair o <= > a un .first contenente sia la chiave (.second) che il valore (at()).

In C ++ 11, puoi anche utilizzare std::out_of_range per <=>. Se l'elemento non esiste, la funzione genera un'eccezione <=>, in contrasto con <=>.

Altri suggerimenti

Non è possibile utilizzare operator[] su una mappa che è const poiché tale metodo non è _map[key] in quanto consente di modificare la mappa (è possibile assegnare a find). Prova invece a utilizzare il metodo <=>.

Dato che operator[] non ha un sovraccarico const const, esso non può essere utilizzato in modo sicuro in una funzione qualificata const. Ciò è probabilmente dovuto al fatto che l'attuale sovraccarico è stato creato con l'obiettivo di restituire e impostare i valori chiave.

Invece, puoi usare:

VALUE = map.find(KEY)->second;

oppure, in C ++ 11, puoi usare l'operatore at() :

VALUE = map.at(KEY);

Alcune versioni più recenti delle intestazioni GCC (4.1 e 4.2 sulla mia macchina) hanno funzioni di membro non standard map :: at () che sono dichiarate const e lanciano std :: out_of_range se la chiave non è nella mappa.

const mapped_type& at(const key_type& __k) const

Da un riferimento nel commento della funzione, sembra che ciò sia stato suggerito come una nuova funzione membro nella libreria standard.

Innanzitutto, non dovresti usare simboli che iniziano con _ perché sono riservati all'implementazione del linguaggio / al compilatore del compilatore. Sarebbe molto facile per _map essere un errore di sintassi sul compilatore di qualcuno e non avresti nessuno da incolpare se non te stesso.

Se vuoi usare un trattino basso, mettilo alla fine, non all'inizio. Probabilmente hai fatto questo errore perché hai visto del codice Microsoft farlo. Ricorda, scrivono il loro compilatore, quindi potrebbero essere in grado di cavarsela. Anche così, è una cattiva idea.

l'operatore [] non solo restituisce un riferimento, ma crea effettivamente la voce nella mappa. Quindi non stai solo ottenendo una mappatura, se non ce n'è, ne stai creando una. Non è quello che volevi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top