Modèles C ++ - Le guide complet, 2e édition présente le modèle max :
template<typename T>
T max (T a, T b)
{
// if b < a then yield a else yield b
return b < a ? a : b;
}
Et cela explique l'utilisation “b < a ? a : b”
au lieu de “a < b ? b : a”
:
Notez que le modèle max () selon [StepanovNotes] renvoie intentionnellement «b <a? a: b »au lieu de« a <b? b: a ”pour s'assurer que la fonction se comporte correctement même si les deux valeurs sont équivalentes mais non égales.
Comment comprendre " even if the two values are equivalent but not equal.
"? “a < b ? b : a”
semble avoir le même résultat pour moi.
a
etb
sont équivalentes , alors!(a < b) && !(b < a)
est vrai, donca < b
etb < a
sont toutes les deux fausses, donc inb < a ? a : b
,b
est renvoyée, ce qui n'est pas ce que vous voulez ... Vous vouleza < b ? b : a
.a
etb
avecstd::addressof
et. Al.a = max(a, b);
(à plusieurs reprises), vous ne voudrez peut-être pas remplacera
inutilement.a
avec une copie dea
).std::addressof
n'est pas pertinent. En fait, pour le donné,T max(T a, T b)
nous savons déjàaddressof(a) != addressof(b)
.Réponses:
std::max(a, b)
est en effet spécifié pour retournera
lorsque les deux sont équivalents.C'est considéré comme une erreur par Stepanov et d'autres parce que cela brise la propriété utile donnée
a
etb
, vous pouvez toujours les trier{min(a, b), max(a, b)}
; pour cela, vous voudrezmax(a, b)
revenirb
lorsque les arguments sont équivalents.la source
{min(a, b), max(b, a)}
?max(a,b)
renvoyer un si-et-seulement-simin(a,b)
renvoie b, et vice versa afin qu'ils soient inversés l'un par rapport à l'autre et que l'ensemble (non ordonné){min(a,b), max(a,b)}
soit toujours égal à{a,b}
.min
etmax
à autre chose que l' horodatage (la clé de tri) dans ce scénario n'a aucun sens. Les événements (les objets) eux-mêmes ne devraient même pas être comparables si l'égalité n'implique pas l'interchangeabilité. La seule façon{min(a, b), max(a, b)}
fait tout sens comme un mécanisme de tri est si les objets sont interchangeables.Cette réponse explique pourquoi le code donné est erroné d'un point de vue standard C ++, mais il est hors contexte.
Voir la réponse de @ TC pour une explication contextuelle.
La norme définit
std::max(a, b)
comme suit [alg.min.max] ( je souligne):Équivalent ici signifie que
!(a < b) && !(b < a)
c'esttrue
[alg.sorting # 7] .En particulier, si
a
etb
sont équivalents, les deuxa < b
etb < a
sontfalse
, donc la valeur à droite de:
sera renvoyée dans l'opérateur conditionnel, ellea
doit donc être à droite, donc:... semble être la bonne réponse. Il s'agit de la version utilisée par libstdc ++ et libc ++ .
Les informations contenues dans votre devis semblent donc erronées selon la norme actuelle, mais le contexte dans lequel elles sont définies peut être différent.
la source
X
).a<b
etb<a
peuvent tous les deux être faux parce qu'ils ne sont pas ordonnés (un ou les deux NaN, donc==
faux aussi). Cela pourrait être considéré comme une sorte d'équivalence. vaguement lié: lesmaxsd a, b
instructions de x86 implémententa = max(b,a) = b < a ? a : b
. ( Quelle est l'instruction qui donne FP sans branche min et max sur x86? ). L'instruction garde l'opérande source (le deuxième) sur un ordre non ordonné, donc une boucle sur un tableau vous donnera NaN s'il y avait des NaN. Maismax_seen = max(max_seen, a[i])
ignorera les NaN.Le point est celui qui doit être retourné quand ils sont équivalents;
std::max
doit retournera
(c'est-à-dire le premier argument) pour ce cas.Donc
a < b ? b : a
devrait être utilisé; d'autre part,b < a ? a : b;
retournerab
incorrectement.(Comme l'a dit @Holt, la citation semble opposée.)
«les deux valeurs sont équivalentes mais non égales» signifie qu'elles ont la même valeur lorsqu'elles sont comparées, mais qu'elles migth être des objets différents à certains autres aspects.
par exemple
la source
std::max(a, b)
doit revenira
, sia
etb
sont équivalents?a
etb
sont équivalents, alors!(a < b) && !(b < a)
est vrai, donca < b
etb < a
sont faux, alors ...?