Le code suivant indique que le fait de transmettre la carte comme const
dans la operator[]
méthode rejette les qualificatifs:
#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;
}
Est-ce à cause de l'attribution possible qui se produit sur l'accès à la carte? Aucune fonction avec accès à la carte ne peut être déclarée 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
Réponses:
std::map
'soperator []
n'est pas déclaré commeconst
, et ne peut pas être dû à son comportement:Par conséquent, votre fonction ne peut pas être déclarée
const
et utiliser les fichiersoperator[]
.std::map
Lafind()
fonction de vous permet de rechercher une clé sans modifier la carte.find()
renvoie uniterator
, ouconst_iterator
à unstd::pair
contenant à la fois la clé (.first
) et la valeur (.second
).Dans C ++ 11, vous pouvez également utiliser
at()
pourstd::map
. Si l'élément n'existe pas, la fonction lève unestd::out_of_range
exception, contrairement àoperator []
.la source
operator[]
(par exemplefoo[bar] = baz
) et rvalueoperator[]
(par exemplex = foo[bar]
) - ce dernier pourrait certainement être const.Comme
operator[]
n'a pas de surcharge qualifiée const, elle ne peut pas être utilisée en toute sécurité dans une fonction qualifiée const. Cela est probablement dû au fait que la surcharge actuelle a été générée dans le but à la fois de renvoyer et de définir des valeurs de clé.Au lieu de cela, vous pouvez utiliser:
ou, en C ++ 11, vous pouvez utiliser l'
at()
opérateur:la source
map.find(KEY)->second;
n'est pas sûr lorsque les valeurs de la carte sont des chaînes. Il a tendance à imprimer des déchets lorsque la clé n'est pas trouvée.Vous ne pouvez pas utiliser
operator[]
sur une carte telleconst
que cette méthode n'est pasconst
car elle vous permet de modifier la carte (vous pouvez l'attribuer à_map[key]
). Essayezfind
plutôt d' utiliser la méthode.la source
Certaines versions plus récentes des en-têtes GCC (4.1 et 4.2 sur ma machine) ont des fonctions membres non standard map :: at () qui sont déclarées const et lancent std :: out_of_range si la clé n'est pas dans la carte.
À partir d'une référence dans le commentaire de la fonction, il semble que cela a été suggéré comme une nouvelle fonction membre dans la bibliothèque standard.
la source
Tout d'abord, vous ne devez pas utiliser de symboles commençant par _ car ils sont réservés à l'implémentation du langage / au rédacteur du compilateur. Il serait très facile pour _map d'être une erreur de syntaxe sur le compilateur de quelqu'un, et vous n'auriez personne d'autre à blâmer que vous-même.
Si vous souhaitez utiliser un trait de soulignement, placez-le à la fin, pas au début. Vous avez probablement fait cette erreur parce que vous avez vu du code Microsoft le faire. Rappelez-vous, ils écrivent leur propre compilateur, afin qu'ils puissent s'en tirer. Même ainsi, c'est une mauvaise idée.
l'opérateur [] ne renvoie pas seulement une référence, il crée en fait l'entrée dans la carte. Donc, vous n'obtenez pas seulement un mappage, s'il n'y en a pas, vous en créez un. Ce n'est pas ce que vous vouliez.
la source
_
est tout simplement faux. Les identifiants commençant par deux traits de soulignement (__example
) ou les identifiants commençant par un trait de soulignement et une majuscule (_Example
) sont réservés._example
n'est pas réservé.