C ++从可变成员函数存储可变参数包

C++ store variadic pack from variadic member function

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

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++ 中使用可变参数模板还很陌生。在此先感谢您的帮助。

This code works correctly, but does not accomplish my goal. I want to store the function for later use (when the object is clicked). Is it possible to get the function pointer and the variadic pack holding the arguments into member variables? If so, what would be a strategy to do so?

您可以将 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();
 }