编译下面的代码会得到错误消息:type illegal。

int main()
{
    // Compilation error - switch expression of type illegal
    switch(std::string("raj"))
    {
    case"sda":
    }
}

你不能在switch或case中使用字符串。为什么?是否有任何解决方案可以很好地支持类似于打开字符串的逻辑?


当前回答

在c++中,字符串不是一等公民。字符串操作是通过标准库完成的。我想,这就是原因。另外,c++使用分支表优化来优化开关case语句。看看这个链接。

http://en.wikipedia.org/wiki/Switch_statement

其他回答

这是因为c++将开关转换为跳转表。它对输入数据执行简单的操作,并在不进行比较的情况下跳转到适当的地址。因为字符串不是一个数字,而是一个数字数组,所以c++不能从它创建一个跳转表。

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
...

(代码来自维基百科https://en.wikipedia.org/wiki/Branch_table)

你可以使用开关字符串。 你需要的是字符串表,检查每一个字符串

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*/
}

在c++和C语言中,开关只适用于整型。使用if else梯子代替。c++显然可以为字符串实现某种switch语句——我猜没有人认为值得这样做,我同意他们的观点。

这是我前段时间提出的一个解决方案,它完全遵守所请求的语法。

#include <uberswitch/uberswitch.hpp>

int main()
{
    uswitch (std::string("raj"))
    {
        ucase ("sda"): /* ... */ break;  //notice the parenthesis around the value.
    }
}

代码如下:https://github.com/falemagn/uberswitch

c++ 11的更新显然不是上面的@MarmouCorp,而是http://www.codeguru.com/cpp/cpp/cpp_mfc/article.php/c4067/Switch-on-Strings-in-C.htm

使用两个映射在字符串和类enum之间进行转换(比普通enum更好,因为它的值是在它内部的范围内,并且反向查找可以获得良好的错误消息)。

在codeguru代码中使用静态是可能的,因为编译器支持初始化列表,这意味着VS 2013 plus。GCC 4.8.1是可以的,不确定它能兼容多远的时间。

/// <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]);
}