Accesso agli elementi della mappa C ++ const


100

Ho provato a utilizzare l'operatore [] per accedere all'elemento in una mappa C ++ const, ma questo metodo non è riuscito. Ho anche provato a usare "at ()" per fare la stessa cosa. Questa volta ha funzionato. Tuttavia, non sono riuscito a trovare alcun riferimento sull'utilizzo di "at ()" per accedere all'elemento in una mappa C ++ const. "At ()" è una funzione appena aggiunta nella mappa C ++? Dove posso trovare maggiori informazioni su questo? Grazie mille!

Un esempio potrebbe essere il seguente:

#include <iostream>
#include <map>

using namespace std;

int main()
{
        map<int, char> A;
        A[1] = 'b';
        A[3] = 'c';

        const map<int, char> B = A;

        cout << B.at(3) << endl; // it works
        cout << B[3] << endl;  // it does not work

}

Per l'utilizzo di "B [3]", ha restituito i seguenti errori durante la compilazione:

t01.cpp: 14: errore: passaggio di 'const std :: map, std :: allocator>>' come 'questo' argomento di '_Tp & std :: map <_Key, _Tp, _Compare, _Alloc> :: operator [] ( const _Key &) [with _Key = int, _Tp = char, _Compare = std :: less, _Alloc = std :: allocator>] 'scarta qualificatori

Il compilatore utilizzato è g ++ 4.2.1

Risposte:


124

at()è un nuovo metodo per std::mapin C ++ 11.

Piuttosto che inserire un nuovo elemento costruito di default come operator[]se un elemento con la chiave data non esiste, genera std::out_of_rangeun'eccezione. (Questo è simile al comportamento di at()for dequee vector.)

A causa di questo comportamento ha senso che ci sia un constsovraccarico di at(), a differenza del operator[]quale ha sempre il potenziale per cambiare la mappa.


È possibile avere "at" restituire un valore predefinito invece di generare un'eccezione?
user1202136

Sto usando at()con in VS2013 su un progetto impostato per utilizzare il toolkit VS2010. Pensavo che ciò significasse che non stavo usando C ++ 11 ... Ma tuttavia si compila ... ??
domani

1
Ho solo bisogno di commentare che non ha senso omettere l'operatore const [], che potrebbe anche generare un'eccezione per un elemento non mappato invece di cambiare la mappa.
Spencer

@Spencer Sarebbe sorprendente se i sovraccarichi const e non const dell'operatore [] avessero effetti diversi. Normalmente, ci aspettiamo che se alcuni oggetti o riferimenti non const in un programma vengono resi const, il programma continuerà a comportarsi allo stesso modo, fintanto che viene compilato. Consentire solo all'overload non const di generare eccezioni può causare bug che non vengono rilevati fino al runtime.
Brian

@Brian Volevi dire "Consentire solo al sovraccarico const di generare eccezioni"?
Spencer

33

Se un elemento non esiste in a map, lo operator []aggiungerà, cosa che ovviamente non può funzionare in una constmappa, quindi C ++ non definisce una constversione dell'operatore. Questo è un bell'esempio del controllo del tipo del compilatore che impedisce un potenziale errore di runtime.

Nel tuo caso, devi usare findinvece che restituirà solo un (iteratore all'elemento) se esiste, non modificherà mai il file map. Se un elemento non esiste, restituisce un iteratore a quello della mappa end().

atnon esiste e non dovrebbe nemmeno essere compilato. Forse questa è una "estensione del compilatore" (=un insetto nuovo in C ++ 0x).


Lo standard C ++ proibisce all'implementazione di definire funzioni membro aggiuntive non standard nelle classi di libreria?
Tim Martin,

@ Tim, credo che l'interfaccia sia corretta, sì.
Konrad Rudolph,

4

L'operatore [] creerà una nuova voce nella mappa se la chiave data non esiste. Potrebbe quindi cambiare la mappa.

Vedi questo collegamento .


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.