88 votes

Pourquoi est-ce que je ne peux pas accéder aux éléments avec l'opérateur[] dans une const std::map?

J'ai essayé d'utiliser l'operator[] pour accéder à l'élément dans une map const, mais cette méthode a échoué. J'ai également essayé d'utiliser at() pour faire la même chose. Cette fois-ci, ça a marché. Cependant, je n'ai trouvé aucune référence sur l'utilisation de at() pour accéder à un élément dans une map const. Est-ce que at() est une fonction nouvellement ajoutée dans map? Où puis-je trouver plus d'informations à ce sujet? Merci beaucoup!

Un exemple pourrait être le suivant:

#include 
#include 

int main()
{
    std::map A;
    A[1] = 'b';
    A[3] = 'c';

    const std::map B = A;

    std::cout << B.at(3) << std::endl; // ça marche
    std::cout << B[3] << std::endl;    // ça ne marche pas
}

Pour utiliser B[3], cela a retourné les erreurs suivantes lors de la compilation:

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

Le compilateur utilisé est g++ 4.2.1

113voto

Charles Bailey Points 244082

at() est une nouvelle méthode pour std::map en C++11.

Au lieu d'insérer un nouvel élément construit par défaut comme le fait operator[] si un élément avec la clé donnée n'existe pas, il lance une exception std::out_of_range. (Cela est similaire au comportement de at() pour deque et vector.)

En raison de ce comportement, il est logique qu'il y ait une surcharge const de at(), contrairement à operator[] qui a toujours le potentiel de modifier la map.

32voto

Konrad Rudolph Points 231505

Si un élément n'existe pas dans une map, l'opérateur [] l'ajoutera - ce qui évidemment ne peut pas fonctionner dans une const map donc C++ ne définit pas de version const de l'opérateur. C'est un bel exemple du vérificateur de type du compilateur empêchant une erreur potentielle à l'exécution.

Dans votre cas, vous devez utiliser find à la place qui ne retournera que un (itérateur vers l') élément s'il existe, il ne modifiera jamais la map. Si un élément n'existe pas, il retourne un itérateur vers le end() de la map.

at n'existe pas et ne devrait même pas compiler. Peut-être que ceci est une "extension du compilateur" (= un bug nouveau en C++0x).

3voto

vidstige Points 4541

L'opérateur [] créera une nouvelle entrée dans la map si la clé donnée n'existe pas. Il peut ainsi modifier la map.

Voir ce lien.

2voto

Beta Points 37745

Cela me surprend assez, mais la map STL n'a pas d'opérateur d'index const. Autrement dit, B[3] ne peut pas être en lecture seule. D'après le manuel:

Puisque l'opérateur[] pourrait insérer un nouvel élément dans la map, il ne peut pas être une fonction membre constante.

Je n'ai aucune idée à propos de at().

1voto

Jan Schultke Points 151

std::map::operator[] n'a pas de const-qualifier, ce qui signifie que vous ne pouvez pas l'appeler avec un const std::map. Voir aussi Quelle est la signification de 'const' à la fin de la déclaration d'une fonction membre? si vous n'êtes pas familier avec cela.

operator[] renvoie une référence à l'élément, tout comme at, mais il y a une différence clé:

Comme at() n'a pas besoin de modifier la map, il a une surcharge const:

T& at( const Key& key );
const T& at( const Key& key ) const; // <-- c'est ce que manque operator[]

Accès non-mutatif dans un std::map

En plus de ces deux fonctions, il y a trois autres façons d'accéder aux éléments dans un const std::map:

const std::map map = { /* ... */ };

auto a = map.at(key);   // OK, C++11, lance une exception si la clé n'est pas trouvée
auto b = map.find(key); // OK, renvoie un itérateur (peut être égal à .end() si la clé n'est pas trouvée)

auto c = map.count(key);    // OK, renvoie size_type (0 ou 1)
auto d = map.contains(key); // OK, C++20, renvoie bool

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X