Modelos C ++ - O Guia Completo, 2ª Edição, apresenta o modelo máximo :
template<typename T>
T max (T a, T b)
{
// if b < a then yield a else yield b
return b < a ? a : b;
}
E explica como usar, em “b < a ? a : b”
vez de “a < b ? b : a”
:
Observe que o modelo max () de acordo com [StepanovNotes] retorna intencionalmente “b <a? a: b "em vez de" a <b? b: a ”para garantir que a função se comporte corretamente, mesmo que os dois valores sejam equivalentes, mas não iguais.
Como entender " even if the two values are equivalent but not equal.
"? “a < b ? b : a”
parece ter o mesmo resultado para mim.
a
eb
são equivalentes , em seguida,!(a < b) && !(b < a)
é verdade, entãoa < b
eb < a
são ambas falsas, portanto, emb < a ? a : b
,b
é devolvido, o que não é o que você quer ... Você quera < b ? b : a
.a
eb
comstd::addressof
et. al.a = max(a, b);
(repetidamente), talvez você não queira substituí-loa
desnecessariamente.a
por uma cópia dea
).std::addressof
é irrelevante. De fato, peloT max(T a, T b)
que já sabemosaddressof(a) != addressof(b)
.Respostas:
std::max(a, b)
é de fato especificado para retornara
quando os dois forem equivalentes.Isso é considerado um erro por Stepanov e outros porque quebra a propriedade útil que é dada
a
eb
, você sempre pode classificá-los{min(a, b), max(a, b)}
; para isso, você gostariamax(a, b)
de retornarb
quando os argumentos forem equivalentes.fonte
{min(a, b), max(b, a)}
?max(a,b)
retorne um retorno se-e-se-min(a,b)
b, e vice-versa, de modo que eles sejam o inverso um do outro e o conjunto (não ordenado){min(a,b), max(a,b)}
seja sempre igual a{a,b}
.min
emax
a qualquer coisa, exceto o carimbo de data / hora (a chave de classificação) nesse cenário, não faz sentido. Os eventos (os objetos) em si nem deveriam ser comparáveis se a igualdade não implicar intercambialidade. A única maneira{min(a, b), max(a, b)}
faz qualquer sentido como um mecanismo de classificação é se os objetos são intercambiáveis.Esta resposta explica por que o código fornecido está errado do ponto de vista padrão do C ++, mas está fora de contexto.
Veja a resposta do @ TC para uma explicação contextual.
O padrão define da
std::max(a, b)
seguinte forma [alg.min.max] (a ênfase é minha):Equivalente aqui significa que
!(a < b) && !(b < a)
étrue
[alg.sorting # 7] .Em particular, se
a
eb
são equivalentes, ambosa < b
eb < a
sãofalse
, então o valor à direita de:
será retornado no operador condicional, portantoa
, deve estar à direita, portanto:... parece ser a resposta correta. Esta é a versão usada pelo libstdc ++ e libc ++ .
Portanto, as informações em sua cotação parecem erradas de acordo com o padrão atual, mas o contexto em que são definidas pode ser diferente.
fonte
X
).a<b
eb<a
ambos podem ser falsos porque não são ordenados (um ou ambos NaN, o mesmo também==
é falso). Isso pode ser visto como uma espécie de equivalência. vagamente relacionado: amaxsd a, b
instrução do x86 é implementadaa = max(b,a) = b < a ? a : b
. ( Qual é a instrução que fornece FP mínimo e máximo sem ramificação em x86? ). A instrução mantém o operando de origem (o 2º) desordenado, portanto, um loop sobre uma matriz fornecerá NaN se houver NaNs. Masmax_seen = max(max_seen, a[i])
irá ignorar os NaNs.O ponto é qual deles deve ser retornado quando forem equivalentes;
std::max
tem que retornara
(ou seja, o primeiro argumento) para este caso.Então
a < b ? b : a
deve ser usado; por outro lado,b < a ? a : b;
retornaráb
incorretamente.(Como disse @Holt, a citação parece oposta.)
"os dois valores são equivalentes, mas não iguais" significa que eles têm o mesmo valor quando comparados, mas podem ser objetos diferentes em alguns outros aspectos.
por exemplo
fonte
std::max(a, b)
tem que retornara
, sea
eb
é equivalente?a
eb
são equivalentes, então!(a < b) && !(b < a)
é verdade, entãoa < b
eb < a
são falsas, então ...?