map<string, string> dada;
dada["dummy"] = "papy";
cout << dada["pootoo"];
Je suis perplexe parce que je ne sais pas si c'est considéré comme un comportement indéfini ou non. Comment savoir quand je demande une clé qui n'existe pas?
Le map::operator[]
cherche dans la structure de données une valeur correspondant à la clé donnée et renvoie une référence à celle-ci.
S'il ne parvient pas à en trouver un, il crée de manière transparente un élément construit par défaut pour celui-ci. (Si vous ne souhaitez pas ce comportement, vous pouvez utiliser la fonction map::at
à la place.)
Vous pouvez obtenir une liste complète des méthodes de std :: map ici:
http://en.cppreference.com/w/cpp/container/map
Voici la documentation de map::operator[]
à partir du standard C++ actuel ...
T& operator[](const key_type& x);
Effets: S'il n'y a pas de clé équivalente à x dans la carte, insère value_type (x, T()) dans la carte.
Requiert: key_type doit être CopyConstructible et mapped_type doit être DefaultConstructible.
Renvoie: Une référence au type mappé correspondant à x dans * this.
Complexité: logarithmique.
T& operator[](key_type&& x);
Effets: S'il n'y a pas de clé équivalente à x dans la carte, insère value_type (std :: move (x), T()) dans la carte.
Requiert: mapped_type doit être DefaultConstructible.
Renvoie: Une référence au type mappé correspondant à x dans * this.
Complexité: logarithmique.
Si vous essayez d'accéder à un key value
à l'aide de l'opérateur d'indexation []
, deux événements peuvent se produire:
key
. Donc, il retournera le key value
correspondant.key
. Dans ce cas, il ajoutera automatiquement une key
à la carte avec null value
.La clé "pootoo"
n'existe pas dans votre carte. Donc, il va automatiquement ajouter cette key
avec value = ""
(chaîne vide). Et votre programme imprimera une chaîne vide.
Ici, la taille de la carte augmentera de 1
.
Pour rechercher une clé, vous pouvez utiliser map_name.find()
, qui retournera map_name.end()
si la clé n'existe pas. Et aucun key
supplémentaire ne sera ajouté.
Vous pouvez utiliser l'opérateur []
lorsque vous souhaitez définir la valeur d'une clé.
Ce n'est pas un comportement indéfini. Si operator []
ne trouve pas de valeur pour la clé fournie, il en insère une à cette position.
Pour l'opérateur [], si vous essayez d'accéder à une valeur pour une clé inexistante, un nouvel objet de valeur construit par défaut sera placé dans la carte et sa référence renvoyée.
Le operator[]
pour map
renvoie une référence non const et vous pouvez l'affecter de la manière que vous avez indiquée sur votre deuxième ligne. Accéder de cette manière créera un élément construit par défaut de type value
.
Si vous voulez trouver un élément à trouver, une meilleure solution est
iterator find ( const key_type& x )
(ou l'alternative const) qui retournera un itérateur égal à <map>.end()
s'il ne trouve pas la clé ou si vous voulez simplement savoir s'il fait partie de la collection, vous pouvez utiliser
size_type count ( const key_type& x ) const
qui retournera toujours 1 ou 0 pour une carte puisque les clés sont uniques.
Si l'opérateur [] ne trouve pas de valeur pour la clé fournie, il en insère une à cette position.
Mais vous devriez noter que si vous visitez un not exist key
et appelez sa fonction membre, comme mapKV [not_exist_key] .member_fun (), le programme risque de tomber en panne.
Voyons un exemple, testons la classe ci-dessous:
struct MapValue{
int val;
MapValue(int i=0){
cout<<"ctor: "<<i<<endl; val = i;
}
~MapValue(){
cout<<"dtor: "<<val<<endl;
}
friend ostream& operator<<(std::ostream& out, const MapValue& mv){
cout<<"MapValue: "<<mv.val<<endl;
}
string toString(){
cout<<"MapValue: "<<val<<endl;
}
};
Code de test:
cout<<"-------create map<int, MapValue>-------"<<endl;
map<int, MapValue> idName{{1, MapValue(1)}, {2, MapValue(2)}};
cout<<"-----cout key[2]-----"<<endl;
cout<<idName[2]<<endl;
cout<<"-----cout key[5]-----"<<endl;
cout<<idName[5]<<endl;
cout<<"------- runs here means, does't crash-------"<<endl;
Sortie comme ci-dessous:
-------create map<int, MapValue>-------
ctor: 1
ctor: 2
dtor: 2
dtor: 1
dtor: 2
dtor: 1
-----cout key[2]-----
MapValue: 2
-----cout key[5]-----
ctor: 0
MapValue: 0
-------runs here means, does't crash-------
dtor: 0
dtor: 2
dtor: 1
Nous pouvons voir que: idName[5]
invoque la construction de la carte {5, MapValue(0)}
pour l'insérer dans idName.
Mais si, vous appelez la fonction membre par idName[5]
, alors le programme obtient un crash:
cout<<"-------create map<int, MapValue>-------"<<endl;
map<int, MapValue> idName{{1, MapValue(1)}, {2, MapValue(2)}};
idName[5].toString(); // get crash here.
cout<<"------- runs here means, does't crash-------"<<endl;
consultez l’exception out_of_range: http://www.cplusplus.com/reference/stdexcept/out_of_range/
c'est ce que map :: at et map :: operator [] lancera si la clé n'existe pas. Vous pouvez l'attraper de la même manière que l'exemple de vecteur dans le lien.
Vous pouvez également utiliser: http://www.cplusplus.com/reference/map/map/find/
Et vérifier contre la carte :: fin