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

What is better to use inline functions or MACROS in C++ for variable length function pointers

本文关键字:函数 更好 MACROS 于可变 指针 C++      更新时间:2023-10-16

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

代码看起来像这样:

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)

我想使用宏,但不建议使用它们。然而,使用带有函数指针的内联函数似乎会导致一些难以阅读的代码。(我没有看到任何函数指针期望函数的参数数量可变的例子)。

有没有更好/更干净的方法可以做到这一点,而不添加一些过于复杂、不可见的代码。

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,它将分散在各处。

您可以使用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);

如果你需要更动态的东西,只需更换函数模板,该模板具有采用CCD_ 4的函数。你当然也可以使用C++11等同物和lambda。

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

相关文章: