Quelle est la meilleure façon de déterminer si une carte STL contient une valeur pour une clé donnée?
#include <map>
using namespace std;
struct Bar
{
int i;
};
int main()
{
map<int, Bar> m;
Bar b = {0};
Bar b1 = {1};
m[0] = b;
m[1] = b1;
//Bar b2 = m[2];
map<int, Bar>::iterator iter = m.find(2);
Bar b3 = iter->second;
}
En examinant cela dans un débogueur, il semble que ce ne iter
soient que des données poubelles.
Si je commente cette ligne:
Bar b2 = m[2]
Les spectacles de débogage qui b2
est {i = 0}
. (Je suppose que cela signifie que l'utilisation d'un index non défini retournera une structure avec toutes les valeurs vides / non initialisées?)
Aucune de ces méthodes n'est si géniale. Ce que j'aimerais vraiment, c'est une interface comme celle-ci:
bool getValue(int key, Bar& out)
{
if (map contains value for key)
{
out = map[key];
return true;
}
return false;
}
Existe-t-il quelque chose dans ce sens?
Réponses:
Non. Avec la classe de carte stl, vous utilisez
::find()
pour rechercher la carte et comparer l'itérateur retourné àstd::map::end()
alors
Évidemment, vous pouvez écrire votre propre
getValue()
routine si vous le souhaitez (également en C ++, il n'y a aucune raison de l'utiliserout
), mais je soupçonnerais qu'une fois que vous maîtriserez l'utilisation,std::map::find()
vous ne voudrez pas perdre votre temps.De plus, votre code est légèrement faux:
m.find('2');
recherchera sur la carte une valeur clé qui est'2'
. IIRC le compilateur C ++ convertira implicitement «2» en un int, ce qui entraîne la valeur numérique du code ASCII pour «2» qui n'est pas ce que vous voulez.Étant donné que votre type de clé dans cet exemple est que
int
vous souhaitez rechercher comme ceci:m.find(2);
la source
find
indique une intention bien meilleure que lacount
nôtre. De plus,count
ne retourne pas l'article. Si vous lisez la question de l'OP, il veut vérifier l'existence et renvoyer l'élément.find
est-ce que.count
ne fait pas.Tant que la carte n'est pas une carte multiple, l'un des moyens les plus élégants serait d'utiliser la méthode de comptage
Le compte serait de 1 si l'élément est bien présent sur la carte.
la source
operator[]
).find
vous donne laTryGetValue
sémantique de .NET , qui est presque toujours ce que vous (et plus précisément l'OP) voulez.Il existe déjà avec find seulement pas dans cette syntaxe exacte.
Si vous souhaitez accéder à la valeur si elle existe, vous pouvez faire:
Avec C ++ 0x et auto, la syntaxe est plus simple:
Je vous recommande de vous y habituer plutôt que d'essayer de trouver un nouveau mécanisme pour le simplifier. Vous pourriez être en mesure de réduire un peu de code, mais considérez le coût de le faire. Vous avez maintenant introduit une nouvelle fonction que les personnes familiarisées avec C ++ ne pourront pas reconnaître.
Si vous souhaitez malgré tout implémenter cela malgré ces avertissements, alors:
la source
Je viens de remarquer qu'avec C ++ 20 , nous aurons
Cela retournera vrai si map contient un élément avec clé
key
.la source
amap.find
revientamap::end
quand il ne trouve pas ce que vous cherchez - vous êtes censé vérifier cela.la source
Vérifiez la valeur de retour de
find
contreend
.la source
Vous pouvez créer votre fonction getValue avec le code suivant:
la source
out = foundIter->second
out = foundIter->second
plutôt queout = *foundIter
Pour résumer brièvement certaines des autres réponses:
Si vous n'utilisez pas encore C ++ 20, vous pouvez écrire votre propre
mapContainsKey
fonction:Si vous souhaitez éviter de nombreuses surcharges pour
map
vsunordered_map
et différents types de clés et de valeurs, vous pouvez en faire unetemplate
fonction.Si vous utilisez
C++ 20
ou plus tard, il y aura unecontains
fonction intégrée:la source
Si vous souhaitez déterminer si une clé se trouve dans la carte ou non, vous pouvez utiliser la fonction membre find () ou count () de la carte. La fonction find qui est utilisée ici dans l'exemple renvoie sinon l'itérateur à element ou map :: end. En cas de comptage, le comptage renvoie 1 s'il est trouvé, sinon il renvoie zéro (ou autre).
la source
Boost multindex peut être utilisé pour une solution appropriée. La solution suivante n'est pas une meilleure option mais peut être utile dans quelques cas où l'utilisateur attribue une valeur par défaut comme 0 ou NULL à l'initialisation et veut vérifier si la valeur a été modifiée.
la source