Шаблоны C ++ - полное руководство, второе издание, представляет шаблон max :
template<typename T>
T max (T a, T b)
{
// if b < a then yield a else yield b
return b < a ? a : b;
}
И это объясняет использование “b < a ? a : b”
вместо “a < b ? b : a”
:
Обратите внимание, что шаблон max () в соответствии с [StepanovNotes] намеренно возвращает «b <a? a: b »вместо« a <b? b: a ”, чтобы гарантировать, что функция ведет себя правильно, даже если два значения эквивалентны, но не равны.
Как понять " even if the two values are equivalent but not equal.
"? “a < b ? b : a”
кажется, имеют тот же результат для меня.
a
иb
являются эквивалентными , то!(a < b) && !(b < a)
верно, такa < b
иb < a
являются ложными, так и вb < a ? a : b
,b
возвращается, что не то , что вы хотите ... Вы хотитеa < b ? b : a
.a
иb
сstd::addressof
эт. и др.a = max(a, b);
(неоднократно), вы не можете заменитьa
без необходимости.a
копиюa
).std::addressof
имеет значения. На самом деле, для данногоT max(T a, T b)
мы уже знаемaddressof(a) != addressof(b)
.Ответы:
std::max(a, b)
действительно указано возвращать,a
когда два эквивалентны.Степанов и другие считают это ошибкой, потому что это нарушает данное полезное свойство,
a
иb
вы всегда можете их отсортировать{min(a, b), max(a, b)}
; для этого вы хотитеmax(a, b)
вернуть,b
когда аргументы эквивалентны.источник
{min(a, b), max(b, a)}
?max(a,b)
будет возвращать if-and-only-ifmin(a,b)
возвращает b, и наоборот, так что они противоположны друг другу, и (неупорядоченный) набор{min(a,b), max(a,b)}
всегда равен{a,b}
.min
иmax
ко всему, кроме метки времени (ключа сортировки) в этом сценарии, не имеет смысла. Сами события (объекты) не должны быть даже сопоставимы, если равенство не подразумевает взаимозаменяемость. Единственный способ{min(a, b), max(a, b)}
имеет никакого смысла , так как механизм сортировки , если объекты являются взаимозаменяемыми.Этот ответ объясняет, почему данный код является неправильным с точки зрения стандарта C ++, но это вне контекста.
См . Ответ @ TC для контекстного объяснения.
Стандарт определяет
std::max(a, b)
следующее [alg.min.max] (акцент мой):Эквивалент здесь означает, что
!(a < b) && !(b < a)
этоtrue
[alg.sorting # 7] .В частности, если
a
иb
эквивалентны, то и такa < b
иb < a
естьfalse
, поэтому значение справа:
будет возвращено в условный оператор, поэтомуa
должно быть справа, так:... кажется правильным ответом. Это версия, используемая libstdc ++ и libc ++ .
Таким образом, информация в вашей цитате кажется неверной в соответствии с текущим стандартом, но контекст, в котором она определена, может отличаться.
источник
X
).a<b
иb<a
оба могут быть ложными, потому что они неупорядочены (один или оба NaN, поэтому==
тоже ложные) Это можно рассматривать как своего рода эквивалентность. слабо связанный:maxsd a, b
инструкция x86 реализуетa = max(b,a) = b < a ? a : b
. ( Какова инструкция, которая дает минимальные и максимальные FP без ветвей на x86? ). Инструкция сохраняет исходный операнд (2-й) неупорядоченным, поэтому цикл по массиву даст вам NaN, если бы были какие-либо NaN. Ноmax_seen = max(max_seen, a[i])
будут игнорировать NaNs.Дело в том, какой из них должен быть возвращен, когда они эквивалентны;
std::max
должен вернутьa
(т.е. первый аргумент) для этого случая.Так
a < b ? b : a
должно быть использовано; с другой стороны,b < a ? a : b;
вернетсяb
неправильно.(Как сказал @Holt, цитата кажется противоположной.)
«эти два значения эквивалентны, но не равны» означает, что при сравнении они имеют одинаковое значение, но в некоторых других аспектах они могут быть разными объектами.
например
источник
std::max(a, b)
должен вернутьсяa
, еслиa
иb
эквивалентны?a
иb
эквивалентны, то!(a < b) && !(b < a)
верно, такa < b
иb < a
ложно, так ...?