【问题标题】:C++ store variadic pack from variadic member functionC++ 存储来自可变参数成员函数的可变参数包
【发布时间】:2019-05-19 06:35:09
【问题描述】:

我正在构建一个简单的 2D 游戏引擎,并且有一个类能够充当游戏中的按钮。我正在尝试创建一个成员函数,以便用户可以为按钮对象提供一个在单击它时运行的函数,以及该函数的参数。以下是部分完成任务的代码示例:

class Entity{
public:
template <typename ... fnParams, typename ... fnArgs>
void Set_Click_Action(void(*action)(fnParams ... params), fnArgs ... args) {
action(args ...); //this works correctly. However, I do not
                  //want to call the function here, I want
                  //instead to store the function in the Entity
                  //object
}

void function(int i, double j, std::string k){
std::cout << i << '\n' << j << '\n' << k << '\n';
}
int main(){
Entity entity;
entity.Set_Click_Action(function, 12, 12.5, std::string("String"));
}

此代码可以正常工作,但没有实现我的目标。我想存储该功能以供以后使用(单击对象时)。是否可以将函数指针和将参数保存到成员变量中的可变参数包?如果是这样,这样做的策略是什么?我应该指出,我对在 C++ 中使用可变参数模板非常陌生。提前感谢您的帮助。

【问题讨论】:

  • 制作一个 lambda 并将其存储为 std::function&lt;void()&gt;。或者,将Set_Click_Action accept 设为函数对象(然后不需要 fnArgs,因为用户可以传入绑定函数)。

标签: c++ function-pointers variadic-templates variadic-functions member-functions


【解决方案1】:

此代码可以正常工作,但没有实现我的目标。我想存储该功能以供以后使用(单击对象时)。是否可以将函数指针和将参数保存到成员变量中的可变参数包?如果是这样,这样做的策略是什么?

您可以将 action()args... 的调用保存在 lambda 函数中,并将 lambda 函数保存在 std::function

举例

struct Entity
 {
   std::function<void()> l;

   template <typename ... fnParams, typename ... fnArgs>
   void Set_Click_Action (void(*action)(fnParams ... params),
                          fnArgs ... args)
    { l = [=]{ action(args...); }; }
 };

显然你可以添加一个方法Call_Action()来调用函数。

以下是使用Call_Action() 方法的完整工作示例

#include <iostream>
#include <functional>

class Entity
 {
   private:
      std::function<void()> l;

   public:
      template <typename ... fnParams, typename ... fnArgs>
      void Set_Click_Action (void(*action)(fnParams ... params),
                             fnArgs ... args)
       { l = [=]{ action(args...); }; }

      void Call_Action () const
       { l(); }
 };

void function (int i, double j, std::string k)
 { std::cout << i << '\n' << j << '\n' << k << '\n'; }

int main()
 {
   Entity entity;
   entity.Set_Click_Action(function, 12, 12.5, std::string("String"));

   std::cout << "--- post set\n";

   entity.Call_Action();
 }

【讨论】:

  • 效果很好,非常感谢您的快速回复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多