Dlaczego warto używać "b

C++ Templates-The Complete Guide, 2nd Edition wprowadza max szablon:

template<typename T>
T max (T a, T b)
{
  // if b < a then yield a else yield b
  return  b < a ? a : b;
}

I wyjaśnia użycie “b < a ? a : b” zamiast “a < b ? b : a”:

Zwróć uwagę, że szablon max() zgodnie z [StepanovNotes] celowo zwraca " b

Jak zrozumieć "even if the two values are equivalent but not equal."? “a < b ? b : a” wydaje się dla mnie ten sam wynik.

 155
Author: Nan Xiao, 2018-06-13

3 answers

std::max(a, b) jest rzeczywiście określone, aby zwrócić a, gdy oba są równoważne.

Jest to uważane za błąd przez Stepanov i innych, ponieważ łamie użyteczną właściwość a i b, zawsze możesz je sortować za pomocą {min(a, b), max(a, b)}; w tym celu chcesz max(a, b) zwrócić b, gdy argumenty są równoważne.

 151
Author: T.C.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-13 11:15:27

Ta odpowiedź wyjaśnia, dlaczego podany kod jest błędny z punktu widzenia standardu C++, ale jest poza kontekstem.

Zobacz @T. C. ' s answer dla kontekstowego wyjaśnienia.


Norma definiuje std::max(a, b) następująco [alg./ min.max] (akcent jest mój):

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

wymaga : Typ T jest Mniejrównywalny (tabela 18).

zwraca : większą wartość.

uwagi: zwraca pierwszy argument gdy argumenty są równoważne.

Odpowiednik tutaj oznacza, że !(a < b) && !(b < a) jest true [alg.sortowanie # 7] .

W szczególności, jeśli a i b są równoważne, zarówno a < b, jak i b < afalse, więc wartość po prawej stronie : zostanie zwrócona w operatorze warunkowym, więc a musi być po prawej stronie, więc:

a < b ? b : a

...wydaje się być poprawna odpowiedź. Jest to wersja używana przez libstdc++ i libc++.

Więc informacje zawarte w cytacie wydają się błędne zgodnie z aktualnym standardem, ale kontekst, w którym są zdefiniowane, może być inny.

 62
Author: Holt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Chodzi o to, który należy zwrócić, gdy są równoważne; std::max musi zwrócić a (tj. pierwszy argument) w tym przypadku.

Jeśli są równoważne, zwraca a.

Więc a < b ? b : a powinno być użyte; z drugiej strony b < a ? a : b; zwróci b niepoprawnie.

(Jak powiedział @ Holt, cytat wydaje się odwrotnie.)

"obie wartości są równoważne, ale nie równe" oznacza, że mają tę samą wartość podczas porównywania, ale są różne obiekty w innych aspektach.

Np.

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
 21
Author: songyuanyao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-13 10:07:45