可能重复:
C/C++:非整数的switch
您好,我需要在switch case语句中使用字符串。 我目前的解决方案是使用自己的哈希函数计算字符串的哈希值。但问题在于我必须手动预先计算所有字符串的哈希值。是否有更好的方法?
h=_myhash (mystring);
switch (h)
{
case 66452:
.......
case 1342537:
........
}
可能重复:
C/C++:非整数的switch
您好,我需要在switch case语句中使用字符串。 我目前的解决方案是使用自己的哈希函数计算字符串的哈希值。但问题在于我必须手动预先计算所有字符串的哈希值。是否有更好的方法?
h=_myhash (mystring);
switch (h)
{
case 66452:
.......
case 1342537:
........
}
只需使用 if() { } else if () { }
链即可。使用哈希值将是维护的噩梦。switch
旨在成为低级语句,不适合用于字符串比较。
typedef void (*funcPointer)(int);
并创建多个函数以匹配该签名:
void String1Action(int arg);
void String2Action(int arg);
这个映射将会是从 std::string
到 funcPointer
的:
std::map<std::string, funcPointer> stringFunctionMap;
然后添加字符串和函数指针:
stringFunctionMap.add("string1", &String1Action);
我没有测试我刚刚发布的任何代码,这都是我脑海中的想法 :)
void func1() {
}
std::unordered_map<std::string, std::function<void()>> hash_map;
hash_map["Value1"] = &func1;
// .... etc
hash_map[mystring]();
这会在运行时增加一些额外的开销,但可维护性提高数千倍。哈希表提供O(1)的插入、查找等操作,这使它们与汇编风格的跳转表具有相同的复杂度。
if(map.find("foo") == map.end()) { /* not found */ }
- Axel Gneitingif (hash(str) == HASH("some string") ..
HASH(const char*)
表达式转换为整数值。switch
检查它们。我认为Ruslik的建议使用源代码生成是一个很好的想法。但是我不会使用“主”和“生成”的源文件概念。我更愿意有一个代码几乎与你的相同的文件:
h=_myhash (mystring);
switch (h)
{
case 66452: // = hash("Vasia")
.......
case 1342537: // = hash("Petya")
........
}
case NUMBERS: // = hash("SOMESTRING")
行(在此处使用正则表达式),将NUMBERS替换为实际的哈希值,并将修改后的源代码写入临时文件。最后,它将备份源文件并用临时文件替换它。如果您不想让源文件每次都有新的时间戳,程序可以检查是否实际上发生了更改,如果没有,就跳过文件替换。你的问题没有很好的解决方案,所以这里有一个可以的解决方案 ;-)
当断言被禁用时,它可以保持效率;当断言被启用时,如果哈希值错误,它会引发断言错误。
我怀疑 D 编程语言可以在编译时计算哈希值,从而消除了明确编写哈希值的需要。
template <std::size_t h>
struct prehash
{
const your_string_type str;
static const std::size_t hash_value = h;
pre_hash(const your_string_type& s) : str(s)
{
assert(_myhash(s) == hash_value);
}
};
/* ... */
std::size_t h = _myhash(mystring);
static prehash<66452> first_label = "label1";
switch (h) {
case first_label.hash_value:
// ...
;
}
你可以使用字符串作为索引,进而在哈希表中查找函数指针。
编辑:GLib提供了一个哈希表实现,支持将字符串作为键,任意指针作为值:http://library.gnome.org/devel/glib/stable/glib-Hash-Tables.html
如果您追求性能,并且不想每次都通过所有的if
子句(如果有很多)或需要对值进行哈希处理,则可以通过使用enum
向函数发送一些额外信息,或者只需将enum
类型添加到您的结构中。
switch(int)
和switch(string)
具有非常不同的性能特征。请使用if/else if。 - Ed S.