在 C++ 中,case 语句需要一个常量整数值,并且不能与在运行时计算的值一起使用。但是,如果您使用的是 C++11,则可以使用 constexpr 函数生成 case 值 simulate 使用带有 case 语句的字符串。
这使用了一个哈希函数,它接受一个指向字符串的指针并在编译时而不是运行时生成一个值。如果多个字符串生成相同的值(哈希冲突),您会收到熟悉的错误消息,即多个 case 语句使用相同的值。
constexpr unsigned int djb2Hash(const char* str, int index = 0)
{
return !str[index] ? 0x1505 : (djb2Hash(str, index + 1) * 0x21) ^ str[index];
}
djb2Hash 函数可以直接在switch 和case 语句中使用。但是有一个警告,散列函数可能在运行时导致冲突。发生这种情况的概率主要取决于散列函数的质量。此处介绍的解决方案并未尝试解决此问题(但可能会在未来解决)。
void DoSomething(const char *str)
{
switch(djb2Hash(str))
{
case djb2Hash("Hello"): SayHello(); break;
case djb2Hash("World"): SayWorld(); break;
}
}
这很好用,但可能会被认为丑。您可以通过声明处理调用哈希函数的用户定义文字来进一步简化此操作。
// Create a literal type for short-hand case strings
constexpr unsigned int operator"" _C ( const char str[], size_t size)
{
return djb2Hash(str);
}
void DoSomething(const char *str)
{
switch(djb2Hash(str))
{
case "Hello"_C: SayHello(); break;
case "World"_C: SayWorld(); break;
}
}
这在 switch 语句中提供了更直观的字符串用法,但由于用户定义的文字,也可能会被认为有点混乱。
[编辑:添加了关于运行时哈希冲突的注释。非常感谢R. Martinho Fernandes 引起我的注意!]