> I'm going to guess that for:
> switch (typeAexpression) {
> case typeBvalue:
>
> we need that TypeB be constexpr constructible and destructible and that there
> is a weak-ordering, constexpr operator<=>(TypeA, TypeB). An equality operator
> alone won't suffice, because then the order of case labels would matter, which
> seems ill-advised to me. Maybe the ordering can be partial, but I don't know
> for sure.
I think that `constexpr operator<=>` is an excellent choice when selecting a binary decision tree; one cannot
solely rely on `operator==`, but also needs to have a weak order.
I would also like to point out that, of course, one could also use `constexpr operator<` for comparisons here.
This approach is also applied in the equality comparison of `std::map`, where `!(a < b || a > b)` replaces `a ==
b`. For developers, this means they only need to implement `constexpr operator<`, such as in the following
implementation of an `object` class:
struct object
{
int tag;
std::string data;
object(int _tag, std::string _data) : tag(_tag), data(_data) {}
constexpr bool operator<(const object &o) const
{
return (tag != o.tag) ? tag < o.tag : data < o.data;
}
};
constexpr bool operator==(const object &lh, const object &rh)
{
return !(lh < rh || rh < lh);
}
Of course, using switch implies a statement which informs the compiler that the object being switched on is
compared to constants of the same type and performs equality comparisons. This is crucial for the compiler;
therefore, it can safely optimize the switch statement.
As for `if...else if... chains`, these weak relational optimizations may be inadvertently disrupted by developers.
It’s also possible that both operands being compared are variables, which poses significant challenges for
compiler performance optimizations.
I wrote a piece of code equivalent to `switch (string)`, using an `if...else if... chains` structure, as shown
here: https://gcc.godbolt.org/z/bf61o41M6
It appears that the compiler uses a "jump table" and does not employ a "multiway branch", which is interesting.
Additionally, I also wrote equivalent code for `switch (object)`, available here:
I believe that the above code can be further optimized using a binary decision tree, "multiway branch", or
"perfect hash table".
With the comparison of `operator<`, it becomes straightforward to sort the constants being compared, and then
implement a balanced binary tree based on the sorted sequence. This brings significant benefits for `switch`
statements with numerous case branches.
For `object`, we can standardize `operator<`. If developers have not defined their own `operator<`, it’s best to
use the default one provided by the compiler.
Regards