Why the switch statement cannot be applied on strings?

前端 未结 20 2563
离开以前
离开以前 2020-11-22 03:58

Compiling the following code and got the error of type illegal.

int main()
{
    // Compilation error - switch expression of type illegal
    sw         


        
相关标签:
20条回答
  • 2020-11-22 04:18

    The reason why has to do with the type system. C/C++ doesn't really support strings as a type. It does support the idea of a constant char array but it doesn't really fully understand the notion of a string.

    In order to generate the code for a switch statement the compiler must understand what it means for two values to be equal. For items like ints and enums, this is a trivial bit comparison. But how should the compiler compare 2 string values? Case sensitive, insensitive, culture aware, etc ... Without a full awareness of a string this cannot be accurately answered.

    Additionally, C/C++ switch statements are typically generated as branch tables. It's not nearly as easy to generate a branch table for a string style switch.

    0 讨论(0)
  • 2020-11-22 04:19

    The problem is that for reasons of optimization the switch statement in C++ does not work on anything but primitive types, and you can only compare them with compile time constants.

    Presumably the reason for the restriction is that the compiler is able to apply some form of optimization compiling the code down to one cmp instruction and a goto where the address is computed based on the value of the argument at runtime. Since branching and and loops don't play nicely with modern CPUs, this can be an important optimization.

    To go around this, I am afraid you will have to resort to if statements.

    0 讨论(0)
  • 2020-11-22 04:20

    Switches only work with integral types (int, char, bool, etc.). Why not use a map to pair a string with a number and then use that number with the switch?

    0 讨论(0)
  • 2020-11-22 04:22

    More functional workaround to the switch problem:

    class APIHandlerImpl
    {
    
    // define map of "cases"
    std::map<string, std::function<void(server*, websocketpp::connection_hdl, string)>> in_events;
    
    public:
        APIHandlerImpl()
        {
            // bind handler method in constructor
            in_events["/hello"] = std::bind(&APIHandlerImpl::handleHello, this, _1, _2, _3);
            in_events["/bye"] = std::bind(&APIHandlerImpl::handleBye, this, _1, _2, _3);
        }
    
        void onEvent(string event = "/hello", string data = "{}")
        {
            // execute event based on incomming event
            in_events[event](s, hdl, data);
        }
    
        void APIHandlerImpl::handleHello(server* s, websocketpp::connection_hdl hdl, string data)
        {
            // ...
        }
    
        void APIHandlerImpl::handleBye(server* s, websocketpp::connection_hdl hdl, string data)
        {
            // ...
        }
    }
    
    0 讨论(0)
  • 2020-11-22 04:26

    You can't use string in switch case.Only int & char are allowed. Instead you can try enum for representing the string and use it in the switch case block like

    enum MyString(raj,taj,aaj);
    

    Use it int the swich case statement.

    0 讨论(0)
  • 2020-11-22 04:28

    As mentioned previously, compilers like to build lookup tables that optimize switch statements to near O(1) timing whenever possible. Combine this with the fact that the C++ Language doesn't have a string type - std::string is part of the Standard Library which is not part of the Language per se.

    I will offer an alternative that you might want to consider, I've used it in the past to good effect. Instead of switching over the string itself, switch over the result of a hash function that uses the string as input. Your code will be almost as clear as switching over the string if you are using a predetermined set of strings:

    enum string_code {
        eFred,
        eBarney,
        eWilma,
        eBetty,
        ...
    };
    
    string_code hashit (std::string const& inString) {
        if (inString == "Fred") return eFred;
        if (inString == "Barney") return eBarney;
        ...
    }
    
    void foo() {
        switch (hashit(stringValue)) {
        case eFred:
            ...
        case eBarney:
            ...
        }
    }
    

    There are a bunch of obvious optimizations that pretty much follow what the C compiler would do with a switch statement... funny how that happens.

    0 讨论(0)
提交回复
热议问题