C ++ - Vorlagen - In der vollständigen Anleitung, 2. Ausgabe , wird die maximale Vorlage vorgestellt:
template<typename T>
T max (T a, T b)
{
// if b < a then yield a else yield b
return b < a ? a : b;
}
Und es erklärt die Verwendung “b < a ? a : b”
anstelle von “a < b ? b : a”
:
Beachten Sie, dass die Vorlage max () gemäß [StepanovNotes] absichtlich „b <a? a: b “statt„ a <b? b: a ”, um sicherzustellen, dass sich die Funktion auch dann korrekt verhält, wenn die beiden Werte gleich, aber nicht gleich sind.
Wie verstehe ich " even if the two values are equivalent but not equal.
"? “a < b ? b : a”
scheint das gleiche Ergebnis für mich zu haben.
a
undb
sind gleichwertig , so!(a < b) && !(b < a)
wahr ist , soa < b
undb < a
sind beide falsch, so inb < a ? a : b
,b
zurückgeführt wird, das ist nicht das, was Sie wollen ... Sie wollena < b ? b : a
.a
undb
mitstd::addressof
et unterscheiden. al.a = max(a, b);
(wiederholt) tun, möchten Sie möglicherweise nichta
unnötig ersetzen .a
mit einer Kopie von überschreibena
).std::addressof
aber irrelevant. TatsächlichT max(T a, T b)
wissen wir das bereitsaddressof(a) != addressof(b)
.Antworten:
std::max(a, b)
wird in der Tat angegeben, um zurückzukehren,a
wenn die beiden gleichwertig sind.Dies wird von Stepanov und anderen als Fehler angesehen, da es die angegebene nützliche Eigenschaft verletzt
a
undb
Sie sie jederzeit sortieren können{min(a, b), max(a, b)}
. Dafür möchten Siemax(a, b)
zurückkehren,b
wenn die Argumente gleichwertig sind.quelle
{min(a, b), max(b, a)}
?max(a,b)
a genau dann zurückzugeben, wennmin(a,b)
b zurückgegeben wird, und umgekehrt, so dass sie umgekehrt sind und die (ungeordnete) Menge{min(a,b), max(a,b)}
immer gleich ist{a,b}
.min
undmax
auf alles andere als den Zeitstempel (den Sortierschlüssel) in diesem Szenario macht keinen Sinn. Die Ereignisse (die Objekte) selbst sollten nicht einmal vergleichbar sein, wenn Gleichheit keine Austauschbarkeit impliziert. Der einzige Weg ,{min(a, b), max(a, b)}
macht jeden Sinn als eine Art Mechanismus ist , wenn die Objekte untereinander austauschbar sind.Diese Antwort erklärt, warum der angegebene Code aus Sicht des C ++ - Standards falsch ist, aber nicht im Zusammenhang steht.
Siehe @ TC Antwort für eine kontextuelle Erklärung.
Der Standard definiert
std::max(a, b)
wie folgt [alg.min.max] (Schwerpunkt liegt bei mir):Equivalent hier bedeutet , dass
!(a < b) && !(b < a)
sichtrue
[alg.sorting # 7] .Insbesondere wenn
a
und gleichb
sind, beidea < b
undb < a
sindfalse
, so wird der Wert auf der rechten Seite:
im bedingten Operator zurückgegeben,a
muss also auf der rechten Seite sein, also:... scheint die richtige Antwort zu sein. Dies ist die von libstdc ++ und libc ++ verwendete Version .
Die Informationen in Ihrem Angebot scheinen nach dem aktuellen Standard falsch zu sein, aber der Kontext, in dem sie definiert sind, kann unterschiedlich sein.
quelle
X
).a<b
undb<a
können beide falsch sein, weil sie ungeordnet sind (ein oder beide NaN, also auch==
falsch). Das könnte als eine Art Äquivalenz angesehen werden. lose verwandt: x86-maxsd a, b
Anweisung implementierta = max(b,a) = b < a ? a : b
. ( Was ist die Anweisung, die verzweigungslose FP min und max auf x86 gibt? ). Der Befehl hält den Quelloperanden (den zweiten) ungeordnet, sodass eine Schleife über ein Array NaN ergibt, wenn NaNs vorhanden sind. Abermax_seen = max(max_seen, a[i])
wird NaNs ignorieren.Der Punkt ist, welcher zurückgegeben werden sollte, wenn sie gleichwertig sind;
std::max
mussa
für diesen Fall zurückgeben (dh das erste Argument).Also
a < b ? b : a
sollte verwendet werden; auf der anderen Seiteb < a ? a : b;
wirdb
falsch zurückgegeben.(Wie @Holt sagte, scheint das Zitat entgegengesetzt zu sein.)
"Die beiden Werte sind äquivalent, aber nicht gleich" bedeutet, dass sie beim Vergleich den gleichen Wert haben, aber in einigen anderen Aspekten unterschiedliche Objekte sein können.
z.B
quelle
std::max(a, b)
zurückkehren müssena
, wenna
undb
gleichwertig sind?a
undb
gleichwertig sind, dann!(a < b) && !(b < a)
ist wahr, alsoa < b
undb < a
sind falsch, also ...?