是否可以,以及如何使用std::map
个函数可以接受任意数量的参数并返回任何可以转换为std::string
的类型?
我尝试过使用std::function
,但在声明std::map
时,我仍然总是需要指定函数允许的参数类型。例如std::map<int,std::function<
INT,BOOL >>
。
我还尝试了多种可变函数和派生类的变体,但似乎都没有给我我需要的东西。
我也看过一些我不太了解的lambda例子,但仍然不确定这是否是正确的方法。
原则上我想要实现的是将任何类型或形式的功能绑定到可以在键盘上按下的每个键。查看我在视觉上如何想象这个地图的图像:link to image 按键时,必须调用与键颜色对应的功能。
答案 0 :(得分:0)
您可能有一段或多段调用这些函数的代码取决于键击:
if (key_pressed == 'q') {
f3(some_boolean_variable);
} else if (key_pressed == 'f') {
f4(some_string_variable);
}
即使您有某种方法可以使用从键到功能的映射,也无法指定如何选择这些变量并将其传递到所选函数而不枚举所有函数(也就是说,使用映射)。
我的建议:
1)使用lambda捕获和std::bind
来生成(不调用)这些函数时已有的内容。
std::map<char, std::function<void(int)>> m;
m['m'] = [](int) {...};
string s = ... // suppose you already know what s should be.
m['i'] = [s](int) {...};
2)尝试重新设计以使用相同的签名,例如std::function<void(const ContextData&)>
using std::experimental::optional;
using std::tuple;
struct ContextData {
optional<bool> bool_value;
optional<tuple<int, string>> f2_args;
optional<tuple<int, string, bool, float, int, int, int>> f5_args;
};
请注意,上面可能会以蹩脚的方式解决您的问题,但这不是一个好的设计。只有当它看起来干净,易于理解且有意义时,才使用这个“一堆可选值”模式。
3)如果您无法想出干净的ContextData,请使用boost::variant
甚至boost::any
。明智地使用它们。
std::map<char, std::function<void(boost::any)>> m;
using std::tuple;
using std::tie;
using boost::any;
using boost::any_cast;
m['i'] = [](any data) {
int i;
std::string s;
// May throw.
tie(i, s) = any_cast<tuple<bool, std::string>>(data);
// use i and s
};
如果我是你,我会重新设计以使参数列表保持一致。这不仅仅是为了让编译器开心;它更像是以理性的,非特定的方式组织逻辑。