编译下面的代码会得到错误消息: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中使用字符串。为什么?是否有任何解决方案可以很好地支持类似于打开字符串的逻辑?
当前回答
在c++中,你只能在int和char上使用switch语句
其他回答
C++
Constexpr哈希函数:
constexpr unsigned int hash(const char *s, int off = 0) {
return !s[off] ? 5381 : (hash(s, off+1)*33) ^ s[off];
}
switch( hash(str) ){
case hash("one") : // do something
case hash("two") : // do something
}
更新:
上面的例子是c++ 11。这里的constexpr函数必须是单语句。这在接下来的c++版本中得到了放宽。
在c++ 14和c++ 17中,你可以使用以下哈希函数:
constexpr uint32_t hash(const char* data, size_t const size) noexcept{
uint32_t hash = 5381;
for(const char *c = data; c < data + size; ++c)
hash = ((hash << 5) + hash) + (unsigned char) *c;
return hash;
}
c++ 17也有std::string_view,所以你可以用它来代替const char *。
在c++ 20中,您可以尝试使用consteval。
这是我前段时间提出的一个解决方案,它完全遵守所请求的语法。
#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++将开关转换为跳转表。它对输入数据执行简单的操作,并在不进行比较的情况下跳转到适当的地址。因为字符串不是一个数字,而是一个数字数组,所以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)
问题是,由于优化的原因,c++中的switch语句只能用于基本类型,你只能将它们与编译时常量进行比较。
这种限制的原因可能是编译器能够应用某种形式的优化,将代码编译为一个cmp指令和一个goto,其中地址是根据运行时参数的值计算的。由于分支和循环在现代cpu上不能很好地发挥作用,因此这可能是一个重要的优化。
要解决这个问题,恐怕你将不得不求助于if语句。
在c++和C语言中,开关只适用于整型。使用if else梯子代替。c++显然可以为字符串实现某种switch语句——我猜没有人认为值得这样做,我同意他们的观点。