The main thing lacking from this entire thread has been any semblance of a discussion of codegen.
The reason C supported `switch` from the beginning is that integers can be put into jump tables:
    switch (i) {
      case 1: case 4: ~~
      case 2: ~~
      case 5: ~~
    }
turns into the codegen equivalent of (Godbolt)
    if (1 <= i && i <= 5) {
      Address table[] = {&&a1, &&a2, &&pass, &&a1, &&a5};
      goto *table[i];
    a1: ~~
    a2: ~~
    a5: ~~
    pass: ;
    }

It would be very cool if C++ could do that for arbitrary user-defined types such as `std::string`... but let's start super simple, with a type where we needn't even think about hashing yet — just a simple wrapped integer.
    class WrappedInt {
      int i_;
    public:
      constexpr WrappedInt(int i) : i_(i) {}
      std::strong_ordering operator<=>(const WrappedInt& rhs) const;
      bool operator==(const WrappedInt& rhs) const;
    };
    int main(int argc, char **argv) {
      auto w = WrappedInt(argc);
      switch (w) {
        case WrappedInt(1): case WrappedInt(4): ~~
        case WrappedInt(2): ~~
        case WrappedInt(5): ~~
      }
    }

Notice that WrappedInt doesn't have a conversion to `int`. (If it did, we could just switch on that, which would make this whole feature unnecessary.) All it has, so far, is comparison operators, which are obviously not good enough to build a jump table in the codegen.
So (this is a probably-rhetorical question directed at @ZhaoYunshan) what API would you have to require of the author of WrappedInt in order to make their type "switch-able"?

Remember, the `switch` statement is not just syntactic sugar for an if-else-if chain of `operator==` comparisons. That chain is slow, and we can already write it by hand if that's what we mean. If you want `switch` for user-defined types, you'll have to explain how to codegen it.  Without any idea how to codegen it, you're not doing language design — you're just stringing words together in teletype font.

HTH,
Arthur



On Tue, May 20, 2025 at 7:38 AM Zhao YunShan via Std-Proposals <std-proposals@lists.isocpp.org> wrote:

    In C++, the switch statement is a fundamental control-flow construct originally designed to work only with integer types (intcharenum, etc.). However, in real-world development, programmers often need to handle string-based (std::string) branching logic. While the standard syntax does not natively support strings, well-structured design patterns can still leverage switch-like behavior to replace lengthy if...else if chains, significantly improving code readability and conciseness.

#include <iostream>
#include <string>
int main()
{
    std::string router;
    switch (router)
    {
    case "cpp":
        std::cout << "cpp router selected.";
        break;
    case "hpp":
        std::cout << "hpp router selected.";
        break;
    default:
        std::cout << "Unknown router type.";
        break;
    }
    return 0;
}


By leveraging compile-time static analysis, switch statements can be optimized into various efficient data structures:

    Jump tables for few cases,
    Balanced binary search for many branches,
    Hash tables where supported.

This ensures optimal time complexity (O(1) to O(log n)) even with large branch sets.

--
Std-Proposals mailing list
Std-Proposals@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals