Question

Le code suivant indique que le fait de transmettre la carte en tant que const à la operator[] méthode ignorent 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 des 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

Était-ce utile?

La solution

Les std::map s operator [] ne sont pas déclarés comme const, et ne peut pas être dû à son comportement:

  

T & amp; opérateur [] (const Key & amp; key)

     

Renvoie une référence à la valeur mappée sur une clé équivalente à une clé, en effectuant une insertion si cette clé n'existe pas déjà.

Par conséquent, votre fonction ne peut pas être déclarée operator[] et utilisez le find() de la carte.

La

iterator fonction const_iterator vous permet de: recherchez une clé sans modifier la carte.

std::pair renvoie un .first, ou <= > vers un .second contenant à la fois la clé (at()) et le valeur (std::out_of_range).

En C ++ 11, vous pouvez également utiliser <=> pour <=>. Si l'élément n'existe pas, la fonction lève une exception <=>, contrairement à <=>.

Autres conseils

Vous ne pouvez pas utiliser operator[] sur une carte const car cette méthode n'est pas _map[key] car elle vous permet de modifier la carte (vous pouvez l'attribuer à find). Essayez d’utiliser la <=> méthode à la place.

Etant donné que operator[] n'a pas de surcharge qualifiée de type const, elle ne peut pas être utilisé en toute sécurité dans une fonction qualifiée const. Ceci est probablement dû au fait que la surcharge actuelle a été créée dans le but de renvoyer et de définir des valeurs de clé.

Au lieu de cela, vous pouvez utiliser:

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

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

VALUE = map.at(KEY);

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.

Premièrement, vous ne devriez pas utiliser de symboles commençant par _ car ils sont réservés au rédacteur de la mise en oeuvre du langage et 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 à blâmer sauf vous-même.

Si vous souhaitez utiliser un trait de soulignement, placez-le à la fin, pas au début. Vous avez probablement commis cette erreur parce que vous avez vu du code Microsoft le faire. Rappelez-vous qu'ils écrivent leur propre compilateur afin de pouvoir s'en sortir. Malgré tout, 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 simplement un mappage, s’il n’en existe pas, vous en créez un. Ce n'est pas ce que vous vouliez.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top