Wie funktioniert die vergleichen Funktion std::map in C++ funktionieren, wenn es reflexiv wahr?
Ich habe eine Karte in meinem Projekt.
Jedes mal, wenn ich das einfügen ein neues element, ich will, um sicherzustellen, dass die Schlüssel für das neue element einzufügen ist, die mindestens eine minimale Breite, abgesehen von anderen Elementen in der map. Dazu schrieb ich eine benutzerdefinierte Klasse vergleichen wie diesem:
class PulseCompare
{
public:
PulseCompare(int minwidth_):minwidth(minwidth_){};
bool operator()(const int x, const int y) const {
if(abs(x-y)>minwidth) return false;
else return true;
}
private:
int minwidth;
};
erstellt und die Karte wie diese:
std::map<int,float,PulseCompare> pulsemap(PulseCompare(256));
und bevor ich ein element einzufügen verwende ich die map.find
Methode wie diese:
if ( pulsemap.find(1600) == pulsemap.end() ) {
//not found so I can insert
} else {
//found
}
Aber das problem ist, dass wenn die Karte versucht reflexartig vergleichen mit den oben genannten vergleichen Funktion durch vertauschen der Werte von x
und y
, wäre es ein true
für beide Fälle das in der Regel nicht der Fall mit den normalen Vergleichsoperatoren wie <
und >
Auf dem cplusplus Dokumentation std::map::key_comp
hier es sagt, und ich zitiere
Vergleich Objekt von einer map-Objekt wird festgelegt, auf Bau. Ihr Typ (Mitglied key_compare) ist das Dritte template-parameter der map-Vorlage. Standardmäßig ist dies ein Gegenstand weniger, das gibt das gleiche wie operator "<".
Dieses Objekt bestimmt die Reihenfolge der Elemente im container: es ist ein Funktionszeiger oder ein Objekt Funktion, die zwei Argumente des gleichen Typs wie die element-Tasten, und gibt true zurück, wenn das erste argument wird als zu gehen, bevor der zweite in der strict weak ordering definiert ist, und false sonst.
Beiden Schlüssel werden als gleichwertig angesehen, wenn key_comp gibt false zurück, reflexiv (D. H., egal, in welcher Reihenfolge die Schlüssel übergeben werden als Argumente).
Aber nicht sagen, über einen Fall, wo es reflexartig true
. Kann mir jemand sagen, was sein Verhalten dann? Oder sollte ich dies tun, Intervall-Vergleich nur durch Iteration über die gesamte Karte?
- Sie wollen wissen, was passiert, wenn a>b und b>a... Gott, ich hoffe, das Universum ist nicht kaputt
- Ich bin mir nicht sicher, wie Sie Sie auch
std::map<int,float> pulsemap(PulseCompare(256));
ist arbeiten - übergeben Sie den Gegenstand vergleichen, als constructor-argument
- Könnten Sie bitte sagen, wie genau dein Beispiel hier, (Aktien den link) habe ich noch nie verwendet.
- furchtbar Leid. nur klar, dass es war ein Tippfehler es. Ich hatte zu geben, vergleichen Sie die Klasse in der template-bevor ich es über den Streit. Ich bearbeitet jetzt. Ich denke, jetzt, es macht die Dinge klar.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Warum nicht einfach diese als Komparator?
Hier ist ein funktionierendes Beispiel: http://coliru.stacked-crooked.com/a/e115d3a2f6714773
compare(a,b)
um zu sehen, ob "a < b" und dann wird es callcompare(b,a)
um zu sehen, obb < a
. Sie halten zu schreiben versucht, eine Vergleich-Funktion, die prüft, "a = b", wenn alles, was Sie schreiben müssen, ist die Rückgabe "ein" < b".std::map
muss eine strenge schwache bestellen der Objekte.std::map
produzieren zu undefiniertem Verhalten.Hinweis: Es ist generell einfacher, einfach den Komparator bieten eine gesamte Bestellung.
Darüber hinaus lassen Sie uns beschreiben, was eine strenge schwache Bestellung erfordert. Hier mache ich Auszüge aus C++ 2011, Abschnitt 25.4.
Compator comp;
ich werde beziehen sich aufcomp(lhs, rhs)
eine Funktion, die einen booleschen Wert zurückgibt. Es ist hilfreich, daran zu denken, wielhs < rhs
.equiv(lhs, rhs)
. Dieser ist definiert als(!comp(lhs, rhs) && !comp(rhs, lhs))
. Also!(lhs < rhs) && !(rhs < lhs)
.Sind wir verpflichtet, die folgenden Regeln halten:
comp(a, b)
impliziert!comp(b, a)
, undcomp(a, a)
ist falsch.Eigentlich, wenn Sie schreiben Sie Ihre Komparator diese Weise sollte es funktionieren:
Und Sie brauchen nicht zu verwenden, bevor Sie einfügen, werden Sie doppelte Arbeit. Nur versuchen einzufügen, wenn eine solche Taste vorhanden ist, anzeigen abzulehnen, die insertion.
std::map::insert
gibt auchstd::pair<iterator,bool>
so können Sie überprüfen, ob die insertion erfolgreich war oder nicht.std::map
in Ihrer Bibliothek.operator()
gibt false zurück, für beide(a,b)
und(b,a)
), ob Sie schon vorher genannt finden, ist irrelevant.else
Teil. Wie lange, wie nie legen Sie einen Wert, der vergleicht, wie gleich zu einem vorhandenen Wert in der Karte, sollten Sie ok sein.map[100] = 10; map[101] = 15
. Das Endergebnis ist eine Karte, die hatmap[100] == 15
, nichtmap[101] == 15
. Also in deinem Beispiel am Ende, die Karte wird nur über 2 Tasten in:{100, 201}
std::map
Umsetzung ist anders. Versuchen Sie, die 101, dann 100, dann 201. Ihre Karte wird nur 101 und nicht 100 oder 201. Aber das zugrunde liegende problem ist, wenn Sie eine Vergleich-Funktion, die ist nicht schwach, um die Ergebnisse nicht definiert wird, so etwas passieren könnte101
, dann100
, dann201
, wird die Karte nur101
. AboveSie behauptet, dass das einfügen100
, dann201
, dann150
Ergebnis wäre eine Karte mit{150, 201}
. Aber das ist nicht das, was führen würde. Sie würden das Ergebnis mit einer Karte mit{100, 201}
. Außerdem, ich Rede nicht über eine Umsetzung, ich spreche von den standard-Anforderungen für das Objekt.std::map
das ist das, was passieren könnte. Die der standard nicht spezifiziert, ob eine neu eingefügte Schlüssel, der vergleicht gleich einen alten Schlüssel ersetzt oder nicht. Es könnte davon abhängen, ob Siestd::map::insert
oderstd::map::operator[]
zum einfügen neuer Werte. Der standard sagt nur seinen undefinierten Verhalten, so dass nichts passieren kannstd::map::operator[]
. Abschnitt 23.4.4.3 Absatz 1: "Effekte: Wenn es keinen Schlüssel entspricht x in der Karte, Beilagen value_type(x, T()) in die Karte." Also, wir werden nicht überschreiben Sie die Taste gibt es. Und fürstd::map::insert
, wir werden Auszug aus der Tabelle 102. "Fügt t, wenn und nur wenn es kein element in den container mit der Taste entspricht der Taste t."