Wie schreibt man eine operator () oder weniger als functor ordentlicher als eine trivalue-compare-Funktion?

8

Schreiben eines Operators & lt; () für eine Struktur scheint klarer zu sein als das Schreiben des klassischen Trivalue-Vergleichs.

zum Beispiel zum Sortieren der folgenden

%Vor%

Sie können einen Operator & lt; ()

schreiben %Vor%

oder eine trivalue Funktion ( normalerweise in der folgenden Weise )

%Vor%

Ersteres ist klarer, daher kann man sagen, dass es bessere Codequalität gibt. Letzteres zwingt Sie, an 3 Fälle zu denken, was den Code verkompliziert.

Aber dieser Gedanke trügt in komplexeren Strukturen:

%Vor%

das Folgende ist klar, und Anfänger neigen dazu, es so zu schreiben

%Vor%

aber es ist falsch ! Sie können damit nicht richtig sortieren!

Und es braucht etwas Zeit, um das zu denken Sie müssen es tatsächlich so schreiben

%Vor%

damit es richtig funktioniert.

Können Sie und Sie diese Vergleichsfunktion auf eine schönere / klarere Art und Weise schreiben? Die alte Trivalue-Vergleichsfunktion hat Sie zumindest dazu gebracht, an & gt ;, & lt; und == Fälle zu denken.

    
Grim Fandango 05.10.2010, 15:04
quelle

7 Antworten

3

Die Sache ist, dass es Ihnen gut geht, wenn Sie nur eine Trivalue-Vergleichsfunktion deklarieren, wenn Sie alle Operatoren automatisch generieren mit: Ссылка

    
Let_Me_Be 05.10.2010, 15:09
quelle
5

Wenn mir Leistung oder Compiler-Spuck egal sind, tendiere ich dazu, dies zu benutzen:

%Vor%

Und für eine etwas billiger in Bezug auf Kopien Version:

%Vor%

Übrigens funktioniert die zweite Version auch mit lvalues.

    
MSN 05.10.2010 15:52
quelle
4

Ich mag es so:

%Vor%

EDIT: Beachten Sie, dass dies auch ein nützliches Feature von std::pair ist - es definiert dies bereits, damit Sie keinen Fehler machen können.

    
Mark B 05.10.2010 15:11
quelle
4

Im Fall int können Sie einfach schreiben:

%Vor%

Nur von Ihnen sprechen über einen Typ, der nicht == mit dem richtigen Verhalten hat, müssen Sie etwas komplexer verwenden, auch dann ist es nicht so schlimm.

%Vor%

Erweiterung auf weitere Mitglieder:

%Vor%

Wenn Sie Ihre Mitglieder in einem Array oder einem anderen Container anordnen können, können Sie std::lexicographical_compare verwenden.

    
Charles Bailey 05.10.2010 15:14
quelle
1

Dies ist nicht klarer oder kürzer als Ihr letztes Beispiel, aber es hat den Vorteil, dass Sie für die Mitglieder nichts anderes als operator< benötigen.

%Vor%

Der letzte Fall kann immer vereinfacht werden, leider müssen die vorherigen Fälle immer die längere Form sein.

%Vor%     
Mark Ransom 05.10.2010 16:26
quelle
0

Eine Sache, die ich einmal gemacht habe, die ein nützliches Idiom zu sein schien, war, eine Vergleichsfunktion zu schreiben, die einen Booleschen Wert zurückgibt, der zwei Argumente plus einen Booleschen Wert, der "Bias" genannt wird, annimmt. Die Funktion gibt true zurück, wenn das erste Argument größer ist oder wenn "bias" gesetzt ist und die beiden Argumente gleich sind. Ein Vergleich, dessen Ergebnis von zwei Untervergleichen abhängt, wäre also:

%Vor%

Beachten Sie, dass dies "zusätzliche" Vergleiche durchführt, da part2s verglichen werden, auch wenn der part1-Vergleich ausreichen würde, um eine Antwort zu liefern, aber redundante Tests auf Gleichheit vermeidet.

Andernfalls könnte man unter Verwendung einer dreiwertigen Logik etwas wie:

machen %Vor%

Die letztere Form vermeidet unnötige Vergleiche und kann leicht auf beliebig viele Felder erweitert werden.

    
supercat 05.10.2010 15:49
quelle
0

Für die erste dreiwertige compare() Funktion

%Vor%

Für den späteren

%Vor%     
Arun 05.10.2010 16:19
quelle

Tags und Links