Plantillas C ++: la guía completa, 2a edición, presenta la plantilla máxima :
template<typename T>
T max (T a, T b)
{
// if b < a then yield a else yield b
return b < a ? a : b;
}
Y explica el uso en “b < a ? a : b”
lugar de “a < b ? b : a”
:
Tenga en cuenta que la plantilla max () de acuerdo con [StepanovNotes] devuelve intencionalmente “b <a? a: b "en lugar de" a <b? b: a ”para garantizar que la función se comporte correctamente incluso si los dos valores son equivalentes pero no iguales.
¿Cómo entender " even if the two values are equivalent but not equal.
"? “a < b ? b : a”
Parece tener el mismo resultado para mí.
a
yb
son equivalentes , entonces!(a < b) && !(b < a)
es cierto, por lo quea < b
yb < a
son falsas, por lo que enb < a ? a : b
,b
se devuelve, que no es lo que quieres ... ¿Quieresa < b ? b : a
.a
yb
constd::addressof
et. Alabama.a = max(a, b);
(repetidamente), es posible que no desee reemplazarloa
innecesariamente.a
con una copia dea
).std::addressof
es irrelevante. De hecho, para lo dadoT max(T a, T b)
ya lo sabemosaddressof(a) != addressof(b)
.Respuestas:
std::max(a, b)
de hecho se especifica que regresea
cuando los dos son equivalentes.Eso es considerado un error por Stepanov y otros porque rompe la propiedad útil que da
a
yb
, siempre puede ordenarlos con{min(a, b), max(a, b)}
; para eso, querrásmax(a, b)
volverb
cuando los argumentos sean equivalentes.fuente
{min(a, b), max(b, a)}
?max(a,b)
devuelva a if-and-only-ifmin(a,b)
devuelve b, y viceversa para que sean al revés y el conjunto (desordenado){min(a,b), max(a,b)}
siempre sea igual a{a,b}
.min
ymax
cualquier otra cosa que no sea la marca de tiempo (la clave de clasificación) en ese escenario no tiene sentido. Los eventos (los objetos) en sí mismos ni siquiera deberían ser comparables si la igualdad no implica intercambiabilidad. La única manera{min(a, b), max(a, b)}
hace ningún sentido como un mecanismo de clasificación es si los objetos son intercambiables.Esta respuesta explica por qué el código dado es incorrecto desde un punto de vista estándar de C ++, pero está fuera de contexto.
Consulte la respuesta de @ TC para obtener una explicación contextual.
El estándar define
std::max(a, b)
lo siguiente [alg.min.max] (el énfasis es mío):Equivalente aquí significa que
!(a < b) && !(b < a)
estrue
[alg.sorting # 7] .En particular, si
a
yb
son equivalentes, ambosa < b
yb < a
sonfalse
, por lo que el valor a la derecha de:
se devolverá en el operador condicional, por loa
que debe estar a la derecha, entonces:... parece ser la respuesta correcta. Esta es la versión utilizada por libstdc ++ y libc ++ .
Entonces, la información en su presupuesto parece incorrecta de acuerdo con el estándar actual, pero el contexto en el que se define puede ser diferente.
fuente
X
).a<b
yb<a
ambos pueden ser falsos porque no están ordenados (uno o ambos NaN, también==
es falso). Eso podría verse como una especie de equivalencia. vagamente relacionado:maxsd a, b
implementos de instrucciones de x86a = max(b,a) = b < a ? a : b
. ( ¿Cuál es la instrucción que proporciona FP min y max sin ramificación en x86? ). La instrucción mantiene el operando de origen (el segundo) en desordenado, por lo que un bucle sobre una matriz le dará NaN si hubiera NaN. Peromax_seen = max(max_seen, a[i])
ignorará los NaNs.El punto es cuál debería devolverse cuando son equivalentes;
std::max
tiene que volvera
(es decir, el primer argumento) para este caso.Por
a < b ? b : a
lo tanto, debe ser utilizado; Por otro lado,b < a ? a : b;
volveráb
incorrectamente.(Como dijo @Holt, la cita parece opuesta).
"los dos valores son equivalentes pero no iguales" significa que tienen el mismo valor cuando se comparan, pero migran como objetos diferentes en otros aspectos.
p.ej
fuente
std::max(a, b)
tiene que volvera
, sia
yb
son equivalentes?a
yb
son equivalentes, entonces!(a < b) && !(b < a)
es verdadero, entoncesa < b
yb < a
son falsos, entonces ...?