Wie lässt sich am besten feststellen, ob eine STL-Zuordnung einen Wert für einen bestimmten Schlüssel enthält?
#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;
}
Wenn man dies in einem Debugger untersucht, sieht es so aus, als wären es iter
nur Mülldaten.
Wenn ich diese Zeile auskommentiere:
Bar b2 = m[2]
Der Debugger zeigt , dass b2
ist {i = 0}
. (Ich vermute, es bedeutet, dass die Verwendung eines undefinierten Index eine Struktur mit allen leeren / nicht initialisierten Werten zurückgibt?)
Keine dieser Methoden ist so großartig. Was ich wirklich möchte, ist eine Schnittstelle wie diese:
bool getValue(int key, Bar& out)
{
if (map contains value for key)
{
out = map[key];
return true;
}
return false;
}
Gibt es etwas in dieser Richtung?
Antworten:
Nein. Mit der stl-Kartenklasse
::find()
durchsuchen Sie die Karte und vergleichen den zurückgegebenen Iterator mitstd::map::end()
so
Natürlich können Sie Ihre eigene
getValue()
Routine schreiben, wenn Sie möchten (auch in C ++ gibt es keinen Grund zur Verwendungout
), aber ich würde vermuten, dass Siestd::map::find()
Ihre Zeit nicht verschwenden möchten , wenn Sie erst einmal den Dreh raus haben.Auch dein Code ist etwas falsch:
m.find('2');
durchsucht die Karte nach einem Schlüsselwert'2'
. IIRC Der C ++ - Compiler konvertiert implizit '2' in ein int, was zu dem numerischen Wert für den ASCII-Code für '2' führt, der nicht Ihren Wünschen entspricht.Da Ihr Schlüsseltyp in diesem Beispiel lautet
int
, möchten Sie wie folgt suchen:m.find(2);
quelle
find
zeigt Absicht weitaus besser alscount
tut. Darüber hinaus wirdcount
der Artikel nicht zurückgegeben. Wenn Sie die Frage des OP lesen, möchte er die Existenz überprüfen und das Element zurückgeben.find
tut das.count
nicht.Solange die Karte keine Multimap ist, besteht eine der elegantesten Möglichkeiten darin, die Zählmethode zu verwenden
Die Anzahl wäre 1, wenn das Element tatsächlich in der Karte vorhanden ist.
quelle
operator[]
. B. mit ).find
gibt Ihnen die .NET-TryGetValue
Semantik, die fast immer das ist, was Sie (und speziell das OP) wollen.Es existiert bereits mit find nur nicht in genau dieser Syntax.
Wenn Sie auf den vorhandenen Wert zugreifen möchten, haben Sie folgende Möglichkeiten:
Mit C ++ 0x und Auto ist die Syntax einfacher:
Ich empfehle Ihnen, sich daran zu gewöhnen, anstatt zu versuchen, einen neuen Mechanismus zu finden, um ihn zu vereinfachen. Möglicherweise können Sie ein wenig Code reduzieren, aber berücksichtigen Sie die Kosten dafür. Jetzt haben Sie eine neue Funktion eingeführt, die mit C ++ vertraute Personen nicht erkennen können.
Wenn Sie dies trotz dieser Warnungen trotzdem implementieren möchten, dann:
quelle
Ich habe gerade bemerkt, dass wir mit C ++ 20 haben werden
Dies gibt true zurück, wenn map ein Element mit key enthält
key
.quelle
amap.find
kehrt zurück,amap::end
wenn es nicht findet, wonach Sie suchen - Sie sollten das überprüfen.quelle
Überprüfen Sie den Rückgabewert von
find
gegenend
.quelle
Sie können Ihre getValue-Funktion mit dem folgenden Code erstellen:
quelle
out = foundIter->second
out = foundIter->second
out = *foundIter
Um einige der anderen Antworten kurz zusammenzufassen:
Wenn Sie C ++ 20 noch nicht verwenden, können Sie Ihre eigene
mapContainsKey
Funktion schreiben :Wenn Sie viele Überladungen für
map
vsunordered_map
und verschiedene Schlüssel- und Werttypen vermeiden möchten , können Sie dies zu einertemplate
Funktion machen.Wenn Sie
C++ 20
oder später verwenden, gibt es eine integriertecontains
Funktion:quelle
Wenn Sie feststellen möchten, ob ein Schlüssel in der Karte vorhanden ist oder nicht, können Sie die Elementfunktion find () oder count () der Karte verwenden. Die hier im Beispiel verwendete Suchfunktion gibt den Iterator ansonsten an element oder map :: end zurück. Im Falle einer Zählung gibt die Zählung 1 zurück, wenn sie gefunden wird, andernfalls gibt sie Null zurück (oder auf andere Weise).
quelle
Boost Multindex kann für die richtige Lösung verwendet werden. Die folgende Lösung ist keine sehr gute Option, kann jedoch in einigen Fällen nützlich sein, in denen der Benutzer bei der Initialisierung einen Standardwert wie 0 oder NULL zuweist und prüfen möchte, ob der Wert geändert wurde.
quelle