155 votes

Pourquoi utiliser «b <a? a: b "au lieu de" a <b? b: a "pour implémenter le modèle max?

Les Modèles C++ - Le Guide Complet de la 2e Édition introduit le max de modèle:

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

Et il explique à l'aide de "b < a ? a : b" au lieu de "a < b ? b : a":

Notez que le max() modèle selon [StepanovNotes] intentionnellement renvoie "b < a ? a : b" au lieu de "a < b ? b:" à s'assurer que la fonction se comporte correctement, même si les deux valeurs sont équivalent, mais n'est pas égal.

Comment comprendre les "even if the two values are equivalent but not equal."? "a < b ? b : a" semble avoir le même résultat pour moi.

152voto

T.C. Points 22510

std::max(a, b) est en effet spécifié pour renvoyer a lorsque les deux sont équivalents.

C'est considéré comme une erreur par Stepanov et d'autres, car cela casse la propriété utile qui, étant donné a et b , vous pouvez toujours les trier avec {min(a, b), max(a, b)} ; pour cela, vous souhaitez que max(a, b) renvoie b lorsque les arguments sont équivalents.

62voto

Holt Points 6689

Cette réponse explique pourquoi le code est faux à partir d'un C++ standard point-de-vue, mais il est hors de contexte.

Voir @T. C. de la réponse pour une explication contextuelle.


La norme définit std::max(a, b) comme suit [alg.min.max] (l'emphase est mienne):

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

Nécessite: Type T est LessThanComparable (Tableau 18).

Retourne: une valeur supérieure.

Remarques: Renvoie le premier argument lorsque les arguments sont équivalentes.

Équivalent ici signifie qu' !(a < b) && !(b < a) est true [alg.le tri#7].

En particulier, si l' a et b sont équivalent, les deux a < b et b < a sont false, de sorte que la valeur sur le droit d' : sera renvoyé à l'opérateur conditionnel, donc, a doit être sur la droite, donc:

a < b ? b : a

...semble être la bonne réponse. C'est la version utilisée par libstdc++ et de la libc++.

Ainsi, les informations dans votre citation semble erroné selon la norme actuelle, mais le contexte dans lequel elle est définie peuvent être différentes.

21voto

songyuanyao Points 2265

Le point qui devra être retourné quand ils sont l'équivalent; std::max a renvoyer a (le premier argument) pour ce cas.

Si elles sont équivalentes, les retours a.

Donc, a < b ? b : a doit être utilisée; d'autre part, b < a ? a : b; sera de retour b de manière incorrecte.

(Comme @Holt dit, la citation semble être le contraire.)

"les deux valeurs sont équivalentes, mais pas l'égalité" signifie qu'ils ont la même valeur lors de la comparaison, mais ils migth être différents objets à certains autres aspects.

par exemple

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X