Wie kann ich das einfügen einer Struktur, die als Schlüssel in einer map?
Ich bekomme einen kompilieren Fehler für den folgenden code, nach dem entfernen der Kommentar-Zeichen aus dem ersten insert
Linie. Ich bin nicht in der Lage, um legen Sie die Struktur in der Karte beim einführen der ganzen zahlen ist in Ordnung.
# include <iostream>
# include <map>
using namespace std;
struct node
{int test;} temp;
int main()
{
temp.test = 24;
int test = 30;
map<node, bool> mymap1;
map<int, bool> mymap2;
//mymap1.insert(make_pair(temp, true));
mymap2.insert(make_pair(test, true));
return 0;
}
Wie kann ich den Fehler beheben?
- Hinweis: Sie können auch die folgende syntax verwenden:
mymap1[temp] = true; mymap2[test] = true;
.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einer std::map Schlüssel gespeichert werden intern in einem binären Suchbaum. Um für Schlüssel und suchte in einer binären Suche Baum, Sie müssen vergleichbar sein. Zum Beispiel, eine Anforderung in einem binären Suchbaum ist, dass eine Links-Kind-Schlüssel ist weniger als die übergeordnete Schlüssel und einem rechten Kind-Schlüssel ist größer als der übergeordneten Schlüssel. Allerdings, wenn die Tasten nicht vergleichbar sind, wie sollen wir sagen, ob die Kinder sich mehr oder weniger als die Eltern? Wir können nicht die form eines Baumes und daher die std::map funktioniert nicht mit diesen Typen.
Müssen Sie einfach zu definieren, der kleiner-als-operator wie folgt:
Dies muss auch ein Freund sein von Ihren Knoten struct, wenn die "test" - Daten Mitglied ist private (Es ist öffentlich nun da Knoten ist derzeit ein struct). Aber wahrscheinlich würde ich es so machen:
struct
s sind standardmäßig öffentlich.getTest()
werden sollte, const-Funktion, sonst wird Ihreoperator<
würde nicht kompilieren.Für eine Art zu dienen als Schlüssel für eine map, es werden bestellt. All das bedeutet, praktisch ist, dass
operator<
muss definiert werden, für den Typ. Wenn Sie eine Globaleoperator<(const node&, const node&)
, das sollte funktionieren; d.h.,Hier ist, wie zu Lesen die Fehlermeldungen:
Erste, ignorieren wir die meisten der " instanziiert von Linien, weil Sie nur darüber zu reden, wie die Vorlagen bekam ausgebaut. Das wichtige ist das Letzte, was unsere source-code, weil es uns sagt, wo der Fehler ausgelöst wurde. Natürlich wussten wir das sowieso, also werden wir überspringen das auch. Wir ignorieren auch den Pfad zu der Bibliothek-header in Frage, weil wir nicht wirklich, wie der compiler speichert seine Sachen.
Also... unser code indirekt fordert
‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = node]’
oder wenn wir tatsächlich tun, dass die substitution, die‘bool std::less<node>::operator()(const node&, const node&) const’
. Und das ist ein problem, weil esno match for ‘operator<’ in ‘__x < __y’
.__x
und__y
sind Variablen, die innerhalb derstd::less
Umsetzung (Sie sollten in der Lage sein, zu erraten, dass viel). Von den Namen, können wir vermuten (und wenn wir studiert hatten, die standard-Bibliothek, die wir so kennen), dassstd::less
ist eine template-Funktion vergleicht zwei Dinge der gleichen Art und gibt an, ob der erste kleiner als der zweite.Wie tut es das? Mithilfe der
operator<
natürlich. Also das ist, was wir tun müssen, um das problem zu lösen: es sagt, dass dieoperator<
gibt es nicht für das, was verglichen wird, also müssen wir es geben. Was wird verglichen?node
s, natürlich. So definieren wiroperator<
für unsere Klasse.Warum tut er das? Damit können wir Funktionen schreiben, annehmen ein-Vergleich-der Betrieb als argument (entweder ein template-argument, oder ein Laufzeit-parameter - aber die erstere ist viel häufiger), und pass
std::less
. Das ist der Grund fürstd::less
's Existenz: es stellt sich die Handlung des Vergleichens, die Dinge in einer Funktion, und die eigentlichen Funktionen sind etwas mehr nützlich.Wie ist dass relevant? Weil, wie die anderen gesagt haben, std::map ist eigentlich vorbei
std::less
als argument. Es ist eigentlich ein Standard-argument, um diestd::map
Vorlage, die verwendet wird, zu vergleichen Elemente. Nachdem alle Teil der Schnittstelle einer Karte ist, dass jeder Schlüssel einmalig ist. Wie willst du das überprüfen Schlüssel für die Einzigartigkeit, wenn Sie nicht können Sie vergleichen? Zugegeben, technisch würden Sie nur haben, um Sie zu vergleichen, für Gleichheit, für diese zu arbeiten. Aber es stellt sich heraus, dass in der Lage, um die Reihenfolge der Tasten macht es möglich, zu erstellen, die eine viel mehr effiziente Datenstruktur. (Sie würde das kennen, wenn Sie tatsächlich nahm Kurse in der Universität über das Programmieren und CS.)Warum war da nicht ein problem mit
int
? Sie sollten in der Lage sein, zu erraten, von jetzt:operator<
bereits natürlich funktioniert fürint
s. Aber Sie müssen sagen, C++, wie es für jeden Anwender-Typen, weil Sie vielleicht etwas anderes im Sinn.C++11
Wie bereits in Andrew Rasmussen Antwort, die Tasten einer
std::map
müssen vergleichbar sein. Sie können jedoch auch eine benutzerdefinierte Vergleich-Objekt auf Ihrer Karte statt der Definitionoperator<
für Ihre Struktur. Da zudem C++11, können Sie eine lambda-Ausdruck statt der Festlegung eines Vergleichs-Objekt. Als Ergebnis, können Sie halten Ihr code so kurz wie folgt:Code auf Ideone