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

发布于 2024-12-28 16:58:38 字数 956 浏览 3 评论 0原文

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

代码看起来像这样:

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)

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

有没有更好/更干净的方法来做到这一点,而无需添加一些过于复杂的不可维护的代码。

I have an application which has a lot of functions which go through all the elements of a menu toolbar.

The code looks like something like this:

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);

It is possible i will change this implementation, or menus could have sub menus. Thus search and replacing code, is not only ugly, but also hardly readable and error prone.

ideally i whould want something like this:

OnAllMenus(functionName,params ...)

so my code whould look like:

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

I wanted to use macro, but their usage is not recommended.
Howerver using inline functions with function pointers seems to lead to some hardly readable code. (And i did not see any example with function pointers expecting variable number of arguments with a function).

Is there any better / cleaner way to do it without addind some overly complex unmaintanable code.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

慈悲佛祖 2025-01-04 16:58:38
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 分散到各处。

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's answer, but variadic templates to stop the stupid boost::binds that will be scattered everywhere.

不美如何 2025-01-04 16:58:38

您可以使用 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 等效项和 lambda。

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

You can use boost::function and boost::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);

If you need something more dynamic simply replace the function
template with a function that takes a boost::function. Of course you
can also use the C++11 equivalents and lambdas.

If you want to get the list of menus into one place and use that list
in different places, I'd recommend Boost.Preprocessor. But you might
want to think twice before resorting to it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文