Why the switch statement cannot be applied on strings?

前端 未结 20 2589
离开以前
离开以前 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:36

    Late to the party, here's a solution I came up with some time ago, which completely abides to the requested syntax.

    #include <uberswitch/uberswitch.hpp>
    
    int main()
    {
        uberswitch (std::string("raj"))
        {
            case ("sda"): /* ... */ break;  //notice the parenthesis around the value.
        }
    }
    

    Here's the code: https://github.com/falemagn/uberswitch

    0 讨论(0)
  • 2020-11-22 04:37
        cout << "\nEnter word to select your choice\n"; 
        cout << "ex to exit program (0)\n";     
        cout << "m     to set month(1)\n";
        cout << "y     to set year(2)\n";
        cout << "rm     to return the month(4)\n";
        cout << "ry     to return year(5)\n";
        cout << "pc     to print the calendar for a month(6)\n";
        cout << "fdc      to print the first day of the month(1)\n";
        cin >> c;
        cout << endl;
        a = c.compare("ex") ?c.compare("m") ?c.compare("y") ? c.compare("rm")?c.compare("ry") ? c.compare("pc") ? c.compare("fdc") ? 7 : 6 :  5  : 4 : 3 : 2 : 1 : 0;
        switch (a)
        {
            case 0:
                return 1;
    
            case 1:                   ///m
            {
                cout << "enter month\n";
                cin >> c;
                cout << endl;
                myCalendar.setMonth(c);
                break;
            }
            case 2:
                cout << "Enter year(yyyy)\n";
                cin >> y;
                cout << endl;
                myCalendar.setYear(y);
                break;
            case 3:
                 myCalendar.getMonth();
                break;
            case 4:
                myCalendar.getYear();
            case 5:
                cout << "Enter month and year\n";
                cin >> c >> y;
                cout << endl;
                myCalendar.almanaq(c,y);
                break;
            case 6:
                break;
    
        }
    
    0 讨论(0)
  • 2020-11-22 04:39

    You can use switch on strings. What you need is table of strings, check every string

    char** strings[4] = {"Banana", "Watermelon", "Apple", "Orange"};
    
    unsigned get_case_string(char* str, char** _strings, unsigned n)
    {
        while(n)
        {
            n--
            if(strcmp(str, _strings[n]) == 0) return n;
        }
        return 0;
    }
    
    unsigned index = get_case_string("Banana", strings, 4);
    
    switch(index)
    {
        case 1: break;/*Found string `Banana`*/
        default: /*No string*/
    }
    
    0 讨论(0)
  • 2020-11-22 04:40

    That's because C++ turns switches into jump tables. It performs a trivial operation on the input data and jumps to the proper address without comparing. Since a string is not a number, but an array of numbers, C++ cannot create a jump table from it.

    movf    INDEX,W     ; move the index value into the W (working) register from memory
    addwf   PCL,F       ; add it to the program counter. each PIC instruction is one byte
                        ; so there is no need to perform any multiplication. 
                        ; Most architectures will transform the index in some way before 
                        ; adding it to the program counter
    
    table                   ; the branch table begins here with this label
        goto    index_zero  ; each of these goto instructions is an unconditional branch
        goto    index_one   ; of code
        goto    index_two
        goto    index_three
    
    index_zero
        ; code is added here to perform whatever action is required when INDEX = zero
        return
    
    index_one
    ...
    

    (code from wikipedia https://en.wikipedia.org/wiki/Branch_table)

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

    C++ 11 update of apparently not @MarmouCorp above but http://www.codeguru.com/cpp/cpp/cpp_mfc/article.php/c4067/Switch-on-Strings-in-C.htm

    Uses two maps to convert between the strings and the class enum (better than plain enum because its values are scoped inside it, and reverse lookup for nice error messages).

    The use of static in the codeguru code is possible with compiler support for initializer lists which means VS 2013 plus. gcc 4.8.1 was ok with it, not sure how much farther back it would be compatible.

    /// <summary>
    /// Enum for String values we want to switch on
    /// </summary>
    enum class TestType
    {
        SetType,
        GetType
    };
    
    /// <summary>
    /// Map from strings to enum values
    /// </summary>
    std::map<std::string, TestType> MnCTest::s_mapStringToTestType =
    {
        { "setType", TestType::SetType },
        { "getType", TestType::GetType }
    };
    
    /// <summary>
    /// Map from enum values to strings
    /// </summary>
    std::map<TestType, std::string> MnCTest::s_mapTestTypeToString
    {
        {TestType::SetType, "setType"}, 
        {TestType::GetType, "getType"}, 
    };
    

    ...

    std::string someString = "setType";
    TestType testType = s_mapStringToTestType[someString];
    switch (testType)
    {
        case TestType::SetType:
            break;
    
        case TestType::GetType:
            break;
    
        default:
            LogError("Unknown TestType ", s_mapTestTypeToString[testType]);
    }
    
    0 讨论(0)
  • 2020-11-22 04:41

    In C++ you can only use a switch statement on int and char

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