1. 问题:
实现用字符串作为switch语句的case子句。形如:
int main(int argc, const char** argv){ const char* strInput = argv[1]; switch(strInput){ case "first": cout << "first... " << endl; break; case "second": cout << "second... " << endl;; break; case "third": ccout << "third... " << endl; break; default: cout << "Default..." << endl; } } |
2. 基本思路
1、用hash函数,设置字符串的hash值,将字符串转换为1个整数;
2、利用c++11自定义文字常量的语法,定义一个constexpr函数,switch的case标签处调用这个constexpr函数。
3. 实现
1、定义一个hash函数,计算出字符串的hash值,将字符串转换为1个整数;
定义: hash_map<const char*, int> CharHash;
struct CharLess : public binary_function<const char*, const char*, bool> { public: result_type operator()(const first_argument_type& _Left, const second_argument_type& _Right) const { return(stricmp(_Left, _Right) < 0 ? true : false); } }; |
然而,无论输入任何字符串,都无法找到对应的整数值。因为输入的字符串是指针,和"a"或"b"字符串常量指针的大小是绝对不会相同。解决方法如下:
写一个仿函数CharLess,继承自仿函数基类binary_function。
int main(int argc, const char** argv){ if (argc <= 1) cout << "input error ... " << endl; const char* strInput = argv[1]; hash_map<const char*, int, hash_compare<const char*, CharLess> > CharHash; CharHash["first"] = 0; CharHash["second"] = 1; CharHash["third"] = 2; if(CharHash.find(strInput) == CharHash.end()){ cout << "input error ... " << endl; return 0; } int nVal = CharHash[strInput]; switch(nVal){ case 0: cout << "first... " << endl; break; case 1: cout << "second..." << endl; break; case 2: cout << "third..." << endl; break; default: cout << "Default..." << endl; } } |
2、利用c++11自定义文字常量的语法,定义一个constexpr函数,switch的case标签处调用这个constexpr函数。
constexpr hash_t hash_compile_time(char const* str, hash_t last_value = basis) { return *str ? hash_compile_time(str+1, (*str ^ last_value) * prime) : last_value; } |
可以写出这样的swich语句:
int main(int argc, const char** argv) { if (argc <= 1) cout << "input error ... " << endl; const char* str = argv[1]; switch(hash_(str)){ case hash_compile_time("first"): cout << " first " << endl; break; case hash_compile_time("second"): cout << " second " << endl; break; case hash_compile_time("third"): cout << " third " << endl; break; default: cout << "Default..." << endl; } } |
上面的语法还不够漂亮,利用自定义文字常量,重载一个operator如下:
constexpr unsigned long long operator "" _hash(char const* p, size_t) { return hash_compile_time(p); } |
int main(int argc, const char** argv) { if (argc <= 1) cout << "input error ... " << endl; const char* str = argv[1]; switch(hash_(str)){ case "first"_hash: cout << " first " << endl; break; case " second"_hash: cout << " second " << endl; break; case " third"_hash: cout << " third " << endl; break; default: cout << "Default..." << endl; } } |
- 4. 参考资料
http://blog.csdn.net/yozidream/article/details/22789147
http://blog.csdn.net/sdhongjun/article/details/4517325