我是C ++的初学者,我已经实现了以下简单的跳转表,但我想知道我是否采用了正确的方法。无论如何我可以改进以下代码吗?
以下代码使用字典(我来自C#背景)来存储函数'指针。
#include <cstdio>
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
void Zero() { printf("Zero\n"); }
void One() { printf("One\n"); }
void Two() { printf("Two\n"); }
void Three() { printf("Three\n"); }
string prompt()
{
printf("Enter number from 0 to 3 or q to quit:\n");
string line;
getline(cin, line);
return line;
}
int main(int argc, const char * argv[]) {
unordered_map<string, void(*)()> map;
map["0"] = Zero;
map["1"] = One;
map["2"] = Two;
map["3"] = Three;
while (true) {
string c = prompt();
if (c == "q") break;
map[c]();
}
return 0;
}
答案 0 :(得分:6)
切换声明怎么样?
switch (c) {
case 0:
printf("Zero\n"); break;
case 1:
printf("One\n"); break;
case 2:
printf("Two\n"); break;
case 3:
printf("Three\n"); break;
default:
break;
}
答案 1 :(得分:3)
请提供更多有关效率的详细信息。你的意思是内存/ CPU周期/传递? 根据你的代码:
auto it = map.find(key);
函数进行搜索并检查输出it != map.end()
值,因此不会创建新元素。std::function<void()>
更低级别控制的术语你可以自定义散列函数和自定义散列表实现。
对于某些数据,将std::map
或std::vector
作为选项进行考虑可能会很有用。
答案 2 :(得分:3)
您可以做的事情并不多,可以让您的代码快速生成#34;没有采用开关解决方案,这打破了拥有一系列功能的原始想法。如果你只打算使用'#39;字符&#39;例如&#39; 0&#39; =&GT; &#39; 9&#39;,&#39; a&#39; =&GT; &#39; Z&#39;你可以躲避字符串所需的内存分配,你也可以使用initializer_list初始化你的地图,如果可行,你也可以使这个数组const静态。
这是我的&#34;优化&#34;代码,如果它有帮助。
inline char prompt() //this function will probably 900% be inlined even if you don't specify the inlike keyword
{
printf("Enter number from 0 to 3 or q to quit:\n");
char v;
while (!(std::cin >> v)); //Just to make sure we get valid input
return v;
}
int main()
{
static const std::unordered_map<char, void(*)()> mymap =
{
{ '0' , Zero },
{ '1' , One },
{ '2' , Two },
{ '3' , Three }
};
while(1)
{
auto it = mymap.find(prompt());
// Without this check, your program will crash if input is invalid.
if (it != mymap.end())
{
it->second();
break;
}
}
return 0;
}
答案 3 :(得分:1)
由于静态查找快速,无论编译器如何,这都会表现得非常好。跳转表与编译器不同。我会使用以下代码,可能有些人会反对这一点,因为global
是坏的。但在发表评论之前,请评估一下
string prompt()
{
printf("Enter number from 0 to 3 or q to quit:\n");
string line;
getline(cin, line);
return line;
}
enum Choice = {ZERO = 0, ONE, TWO, THREE};
static char *choice_str[] = {
"Zero",
"One",
"Two",
"Three"
};
int main(int argc, const char * argv[]) {
while (true) {
string c = prompt();
if (c == "q")
{
break;
}
else {
assert(atoi(c) >= Choice::ZERO && atoi(c) <=Choice::THREE);
printf("%s\n", choice_str[atoi(c)]);
}
}