我有一系列看起来非常相似的函数:它们采用相同的arguement类型并返回字符串。
std::string f1(T arg);
std::string f2(T arg);
std::string f3(T arg);
std::string f4(T arg);
.
.
.
在循环中,根据struct T中的一个变量使用它们。目前为止,我的代码中只有一个大的switch/case
块。
这样做有更好的编码风格吗?大块代码看起来很奇怪。
我希望c ++可以像python一样做eval("f" + str(i) + "(arg))"
块是这样的:
std::string out = "";
switch (arg.tag){
case 1:
out += f1(arg);
break;
case 2:
out += f2(arg);
break;
.
.
.
}
大约二十几个案件
答案 0 :(得分:4)
使用C ++ 11,您可以使用std::function
和地图
#include <map>
#include <functional>
#include <string>
#include <iostream>
std::string f1(int) { return "f1"; }
std::string f2(int) { return "f2"; }
std::map<int, std::function<std::string(int)> > funcs = {
{1,f1},
{2,f2}
};
int main() {
std::cout << funcs[1](100) << "\n";
}
如果没有C ++ 11,您可能要么使用Boost而不是std::function
,要么改为使用自己的类型。您可以使用普通的旧函数指针,但这将排除一些方便的东西(如std::bind
/ boost::bind
,仿函数对象,lambda函数。您还可以使用函数实现的接口定义类型层次结构例如,以下在C ++ 03中工作,除了初始化地图的方式:
#include <map>
#include <functional>
#include <string>
#include <iostream>
std::string f1(int) { return "f1"; }
std::string f2(int) { return "f2"; }
std::map<int, std::string(*)(int)> funcs = {
std::make_pair(1,f1),
std::make_pair(2,f2)
};
int main() {
std::cout << funcs[1](100) << "\n";
}
或者这可以让你编写任何你喜欢的仿函数对象:
#include <map>
#include <string>
#include <iostream>
struct thing {
virtual std::string operator()(int) const = 0;
};
struct f1 : thing {
std::string operator()(int) const { return "f1"; }
};
struct f2 : thing {
std::string operator()(int) const { return "f2"; }
};
// Note the leak - these never get deleted:
std::map<int, thing*> funcs = {
std::make_pair(1,new f1),
std::make_pair(2,new f2)
};
int main() {
std::cout << (*funcs[1])(100) << "\n";
}
答案 1 :(得分:1)
模仿Eval()
的一种方法是拥有地图。映射的关键是函数的名称,值将是指向相应函数的指针。
在这种情况下,您可以通过名称调用地图operator[]
所需的功能。这将以某种方式模拟eval("f" + str(i) + "(arg))"
行为,但它可能仍然不是最适合您的解决方案。