对于可变长度函数指针,在C ++中使用内联函数或MACROS更好

时间:2012-01-24 00:09:07

标签: c++ macros inline function-pointers

我有一个应用程序,它有很多功能,遍历菜单工具栏的所有元素。

代码看起来像这样:

subMenuDefaultMenuShortcuts( ui->fileMenu );
subMenuDefaultMenuShortcuts(ui->editMenu);
subMenuDefaultMenuShortcuts(ui->windowMenu);
subMenuDefaultMenuShortcuts(ui->helpMenu);

subMenuUpdateLabels(ui->fileMenu,hierarchy);
subMenuUpdateLabels(ui->editMenu,hierarchy);
subMenuUpdateLabels(ui->windowMenu,hierarchy);
subMenuUpdateLabels(ui->helpMenu,hierarchy);

我可以更改此实现,或菜单可以有子菜单。因此,搜索和替换代码不仅难看,而且难以读取和容易出错。

理想情况下,我想要这样的东西:

OnAllMenus(functionName,params ...)

所以我的代码应该是这样的:

OnAllMenus(subMenuUpdateLabels)
OnAllMenus(subMenuUpdateLabels,hierarchy)
OnAllMenus(someFunction,hierarchy,argument1,argument2)

我想使用宏,但不推荐使用它们。 使用带函数指针的内联函数的Howerver似乎导致一些难以理解的代码。 (我没有看到任何函数指针的例子,期望带有函数的可变数量的参数)。

如果没有添加一些过于复杂的无法解释的代码,是否有更好/更清洁的方法呢?

2 个答案:

答案 0 :(得分:1)

您可以使用boost::functionboost::bind

template<typename Func>
void for_all_menus(Func f) {
  f(ui->foo);
  f(ui->bar);
  // etc
}

// use
for_all_menus(boost::bind(subMenuLabel, _1, hierarchy));

// with variadic templates
template<typename Func, typename Args...>
struct for_all_menus {
  Func f;
  void operator()(Args&&... args) {
    // umh, I always mess up the syntax
    // you might want to double check this
    f(ui->foo, std::forward<Args>(args)...);
  }
};
template<typename F>
for_all_menus<F> make_for_all_menus(F f) { return for_all_menus<F>{f}; }

// use
auto f = make_for_all_menus(subMenuLabel);
f(hierarchy);

如果您需要更动态的东西,只需更换功能即可 带有boost::function函数的模板。你当然知道 也可以使用C ++ 11等价物和lambdas。

如果您想将菜单列表放在一个位置并使用该列表 在不同的地方,我推荐使用Boost.Preprocessor。但你可能会 在诉诸它之前想要三思而行。

答案 1 :(得分:1)

template<typename FuncPointer, typename ... Args>
void for_all_menus(FuncPointer func, Args ... args)
{
  f(ui->foo,std::forward<Args>(args)...);
  f(ui->bar,std::forward<Args>(args)...);
  // etc
}

// use
for_all_menus(&subMenuLabel, hierarchy);

Pmr的答案,但可变模板可以阻止分散在各处的愚蠢boost::bind