我想创建一个菜单处理程序来替换这样的构造:
void MyClass::handleMenu(MenuID id) {
switch (id) {
case option1: doFunction1(); break;
case option2: doFunction2(true); break;
case option3: memberVariable->doOtherFunction(); break;
}
}
随着菜单项数量的增加,switch 语句也在增加,因此我想更改为一种机制,其中菜单设置有许多函数对象,这些函数对象被调用以响应菜单通知。一些函数可能采用其他参数(在设置时已知),一些可能是对成员函数的调用。
我有一种感觉,它应该看起来像这样:
void MyClass::setupMenu() {
std::map<MenuID, boost::function<void()>> idMap;
idMap[option1] = boost::bind(&MyClass::doFunction1, _1, this);
idMap[option2] = boost::bind(&MyClass::doFunction2, _1, this, true);
idMap[option3] = boost::bind(&MemberClass::doOtherFunction, _1, memberVariable);
}
void MyClass::handleMenu(MenuID id) {
auto f=idMap[id];
f(); // invoke callback
}
但是,我无法获得boost::function
类型和bind
调用的正确组合。也许有些函数可能会返回一个值,这很复杂,但是在菜单处理代码中我们并不关心这个,我们可以将其视为 void。编译器错误往往出现在将结果bind
插入映射的调用中。我错过了一种更简单的方法吗?
编辑:
@frank 的方法有效,但我发现了一个我没有预料到的问题:如果您试图单步调试器中的代码以找到由菜单项执行的函数,那么这非常困难,因为您必须介入boost::bind
在您进行实际的函数调用之前,请先跳过几层代码。很遗憾,调试器没有完全跟上 boost 和 tr1 的前沿。