Sie können einen Funktionszeiger, ein Funktionsobjekt (oder Boost-Lambda) an std :: sort übergeben, um eine strenge schwache Reihenfolge der Elemente des zu sortierenden Containers zu definieren.Verkettung von Ordnungsvergleichselementen (z. B. für std :: sort)
Aber manchmal (genug, dass ich diese mehrmals getroffen habe), möchten Sie in der Lage sein, "primitive" Vergleiche zu verketten.
Ein triviales Beispiel wäre, wenn Sie eine Sammlung von Objekten sortieren würden, die Kontaktdaten darstellen. Manchmal möchten Sie nach
last name, first name, area codesortieren. Andere Male
first name, last name- noch andere Male
age, first name, area code... usw.
Jetzt können Sie sicherlich ein zusätzliches Funktionsobjekt für jeden Fall schreiben, aber das verstößt gegen das DRY-Prinzip - vor allem, wenn jeder Vergleich weniger trivial ist.
Es scheint, als ob Sie in der Lage sein sollten, eine Hierarchie von Vergleichsfunktionen zu schreiben - die Low-Level-Einsen machen die einfachen, primitiven Vergleiche (zB Vorname < Vorname), dann rufen die höherwertigen die nachfolgenden auf (wahrscheinlich Verkettung mit & &, um die Kurzschlussauswertung zu verwenden), um die zusammengesetzten Funktionen zu erzeugen.
Das Problem mit diesem Ansatz ist, dass Std :: sort ein binäres Prädikat nimmt - das Prädikat kann nur ein Bool zurückgeben. Also, wenn Sie sie komponieren, können Sie nicht sagen, ob ein "false" Gleichheit oder größer als bedeutet. Sie können Ihre niedrigeren Prädikate dazu bringen, ein int mit drei Zuständen zurückzugeben - aber dann müssten Sie diese in höhere Prädikate einbetten, bevor sie mit std :: sort allein verwendet werden könnten.
In allem sind dies keine unüberwindbaren Probleme. Es scheint einfach schwieriger als es sein sollte - und lädt sicherlich eine Helfer Bibliothek Implementierung ein.
Wer weiß also schon von einer bereits vorhandenen Bibliothek (vor allem wenn es sich um eine Standard- oder Boost-Bibliothek handelt), die hier helfen könnte - irgendwelche anderen Gedanken zu haben?
[Update]
Wie in einigen Kommentaren erwähnt - ich habe weitergemacht und geschrieben meine eigene Implementierung einer Klasse diese zu verwalten. Es ist ziemlich minimal und hat wahrscheinlich einige Probleme damit. aber auf dieser Grundlage für alle Interessierten ist die Klasse hier:
Und einige Hilfsfunktionen (die Notwendigkeit zu vermeiden Vorlage args angeben) ist hier:
Das Problem mit dieser Implementierung besteht darin, dass Ihre Vergleichsfunktionen auf niedriger Ebene Boole zurückgeben. Sie wollen nur dann zum nächsten Vergleich übergehen, wenn der aktuelle Test * gleich * vergleicht. – philsquared
Sehen Sie meinen eigenen Stich hier, dass ich einen Link zu meiner Antwort auf siukurnin, oben, gepostet habe. Ich kann jetzt tun: Std :: sort (c.begin(), c.end(), MakeCompareChain (f1, f2, f3)); – philsquared
Nein, es funktioniert - wir müssen nur zwei Vergleiche machen (a == b ist das gleiche wie nicht (a