Зачем использовать «b <a?a: b »вместо« a <b?b: a ”для реализации макса шаблона? - PullRequest
0 голосов
/ 13 июня 2018

Шаблоны C ++ - Полное руководство, 2-е издание представляет шаблон 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

Как понять« even if the two values are equivalent but not equal. »?“a < b ? b : a”, кажется, имеют тот же результат для меня.

Ответы [ 3 ]

0 голосов
/ 13 июня 2018

Этот ответ объясняет, почему данный код является неправильным со стандартной точки зрения C ++, но это вне контекста.

См. @ ответ TC для контекстного объяснения.


Стандарт определяет std::max(a, b) следующим образом [alg.min.max] (выделено моё):

template<class T> constexpr const T& max(const T& a, const T& b);

Требуется : тип T является LessThanComparable (Таблица 18).

Возвращает :Чем больше значение.

Примечания : Возвращает первый аргумент, когда аргументы эквивалентны.

Эквивалент здесь означает, что !(a < b) && !(b < a)равно true [alg.sorting # 7] .

В частности, если a и b эквивалентны, оба значения a < b и b < a равны falseТаким образом, значение справа от : будет возвращено в условном операторе, поэтому a должно быть справа, поэтому:

a < b ? b : a

... кажется правильным ответом,Это версия, используемая libstdc ++ и libc ++ .

Таким образом, информация в вашей цитате кажется неверной в соответствии с текущим стандартом, но контекстом, в котором она определенаможет быть другим.

0 голосов
/ 13 июня 2018

std::max(a, b) действительно указывается, чтобы возвращать a, когда оба эквивалентны.

Это считается ошибкой Степанова и других, потому что это нарушает полезное свойство, которое дает a и b, вы всегда можете отсортировать их с помощью {min(a, b), max(a, b)};для этого вам нужно, чтобы max(a, b) возвращал b, когда аргументы эквивалентны.

0 голосов
/ 13 июня 2018

Дело в том, какой из них должен быть возвращен, когда они эквивалентны;std::max должен вернуть a (то есть первый аргумент) для этого случая.

Если они эквивалентны, возвращает a.

Так что a < b ? b : a следует использовать;с другой стороны, b < a ? a : b; вернет b неправильно.

(Как сказал @Holt, цитата кажется противоположной.)

«эти два значения эквивалентны, но не равны» означаетпри сравнении они имеют одинаковое значение, но в некоторых других аспектах они могут быть разными объектами.

например

struct X { int a; int b; };
bool operator< (X lhs, X rhs) { return lhs.a < rhs.a; }
X x1 {0, 1};
X x2 {0, 2};
auto x3 = std::max(x1, x2); // it's guaranteed that an X which cantains {0, 1} is returned
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...