编译下面的代码会得到错误消息:type illegal。
int main()
{
// Compilation error - switch expression of type illegal
switch(std::string("raj"))
{
case"sda":
}
}
你不能在switch或case中使用字符串。为什么?是否有任何解决方案可以很好地支持类似于打开字符串的逻辑?
编译下面的代码会得到错误消息:type illegal。
int main()
{
// Compilation error - switch expression of type illegal
switch(std::string("raj"))
{
case"sda":
}
}
你不能在switch或case中使用字符串。为什么?是否有任何解决方案可以很好地支持类似于打开字符串的逻辑?
当前回答
开关仅适用于整型(int, char, bool等)。为什么不使用映射将字符串与数字配对,然后将该数字与开关使用呢?
其他回答
hare对Nick解决方案的评论真的很酷。这里是完整的代码示例(c++ 11):
constexpr uint32_t hash(const std::string& s) noexcept
{
uint32_t hash = 5381;
for (const auto& c : s)
hash = ((hash << 5) + hash) + (unsigned char)c;
return hash;
}
constexpr inline uint32_t operator"" _(char const* p, size_t) { return hash(p); }
std::string s = "raj";
switch (hash(s)) {
case "sda"_:
// do_something();
break;
default:
break;
}
开关仅适用于整型(int, char, bool等)。为什么不使用映射将字符串与数字配对,然后将该数字与开关使用呢?
在c++中,字符串不是一等公民。字符串操作是通过标准库完成的。我想,这就是原因。另外,c++使用分支表优化来优化开关case语句。看看这个链接。
http://en.wikipedia.org/wiki/Switch_statement
你可以使用开关字符串。 你需要的是字符串表,检查每一个字符串
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*/
}
如前所述,编译器喜欢构建查找表,尽可能地将switch语句优化到接近O(1)的时间。再加上c++语言没有字符串类型——std::string是标准库的一部分,而标准库本身不是语言的一部分。
我将提供一个你可能想要考虑的替代方案,我过去用过它,效果很好。不是切换字符串本身,而是切换使用字符串作为输入的哈希函数的结果。如果你使用一组预先确定的字符串,你的代码几乎和切换字符串一样清晰:
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:
...
}
}
这里有一堆明显的优化,基本上遵循了C编译器对switch语句的处理……真有趣。