125 votes

Qualificatifs de rejet d'accès aux cartes C ++ (const)

Le code suivant indique que le fait de passer la carte en tant que const dans la méthode operator[] supprime les qualificateurs:

 #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'allocation possible qui se produit sur l'accès à la carte? Aucune fonction avec accès à la carte ne peut-elle ê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

169voto

luke Points 16255

std::map de l'opérateur n'est pas déclarée const, et ne peut pas être à cause de son comportement:

T& operator[] (const Clé et clé)

Renvoie une référence à la valeur qui est associée à une clé équivalente à la clé, l'exécution d'insertion si cette clé n'existe pas déjà.

En conséquence, votre fonction ne peut pas être déclarée const, et l'utilisation de la carte de l'opérateur[].

std::map find() fonction vous permet de rechercher une clé sans modification de la carte.

Edit:

find() retourne un itérateur, ou const_iterator à un std::pair contenant à la fois la touche (.en premier lieu) et la valeur (.la seconde).

20voto

Richard Points 5991

Depuis operator[] n'ont pas de const-qualifié de surcharge, il ne peut pas être utilisé en toute sécurité dans un const qualifiés de la fonction. C'est probablement parce que le courant de surcharge a été construit avec l'objectif de les deux de la retourner et de la détermination des principales valeurs.

Au lieu de cela, vous pouvez utiliser:

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

ou, en C++11, vous pouvez utiliser l' at() opérateur:

VALUE = map.at(KEY);

12voto

nrl Points 578

Vous ne pouvez pas utiliser l'opérateur [] sur une carte qui est const, car cette méthode n'est pas constante car elle vous permet de modifier la carte (vous pouvez affecter à _map [clé]). Essayez d'utiliser la méthode find à la place.

7voto

Nathan Kitchen Points 2729

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 jettent std :: out_of_range si la clé n'est pas dans la carte.

 const mapped_type& at(const key_type& __k) const
 

D'après une référence dans le commentaire de la fonction, il semble que cela ait été suggéré en tant que nouvelle fonction membre dans la bibliothèque standard.

0voto

Dov Points 1864

Tout d'abord, vous ne devriez pas être à l'aide de symboles commençant par _ parce qu'ils sont réservés à la langue mise en œuvre/compilateur de l'écrivain. Il serait très facile pour _map être une erreur de syntaxe sur quelqu'un compilateur, et vous n'avez personne à blâmer, mais vous-même.

Si vous souhaitez utiliser un trait de soulignement, de la mettre à la fin, pas au début. Vous avez probablement fait cette erreur, parce que vous avez vu certains de Microsoft code de le faire. Rappelez-vous, ils écrivent leur propre compilateur, de sorte qu'ils peuvent être en mesure de sortir avec elle. De même, c'est une mauvaise idée.

l'opérateur [] non seulement renvoie une référence, il crée l'entrée dans la carte. De sorte que vous ne sont pas seulement obtenir une cartographie, si il n'y est pas, vous en créez un. Ce n'est pas ce que vous souhaitiez.

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