I am implementing a three-way comparison (operator<=>) for an enum class representing Rock-Paper-Scissors. My implementation compiles and returns std::strong_ordering, but I am unsure whether it meets the formal requirements for std::strong_ordering, particularly regarding transitivity.
Here is my code:
#include <compare>
enum class Hand { Rock, Paper, Scissors };
std::strong_ordering operator<=>(Hand a, Hand b) {
if (a == Hand::Paper && b == Hand::Scissors) return std::strong_ordering::less;
if (a == Hand::Scissors && b == Hand::Rock) return std::strong_ordering::less;
if (a == Hand::Rock && b == Hand::Paper) return std::strong_ordering::less;
if (a == b) return std::strong_ordering::equal;
return std::strong_ordering::greater;
}
This implementation introduces a cyclic comparison:
Paper < ScissorsScissors < RockPaper > Rock, breaking transitivity.
I used std::strong_ordering as the return type, since any two values of type enum class Hand are compariable, and all equal values of this type are same.You can see that this code can be compile, and works well on judging the winner of the game. Of course, I can't put a series of values of this enum class into a sort function or
std::set, etc., which introduces an undefined behavior.
I noticed that the C++ draft standard (N4950, §17.11.2[cmp.categories.pre]/2) contains a note stating that "The type strong_ordering corresponds to the term total ordering in mathematics." However, since this is only a note, I could not find an explicit normative requirement in the main text that std::strong_ordering must always represent a total order, particularly the transitivity requirement.
Is std::strong_ordering formally required to enforce a total order, or is the note just an informal explanation?
If a total order is required, is my implementation invalid because it breaks transitivity?
strong_orderingare the same as that for a total order in the mathematical sense. There does not have to be more normative text that makes them the same.strong_orderingas the same as total ordering was exaggerated.strict_weak_order!=weak_orderingthough...