Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ store variadic pack from variadic member function

I am working on building a simple 2D game engine and have a class which is capable of acting as a button in a game. I am trying to make a member function such that the user can give the button object a function to run when it is clicked, as well as the parameters for that function. Here is a sample of the code which partially completes the task:

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

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? I should point out that I am pretty new to using variadic templates in C++. Thanks in advance for any help.

like image 937
Jamman00 Avatar asked Nov 18 '25 16:11

Jamman00


1 Answers

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?

You can save the call of action(), and the args..., in a lambda function and save the lambda function in a std::function

By example

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

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

Obviously you can add a method Call_Action() to call the function.

The following is a full working example with a Call_Action() method

#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();
 }
like image 97
max66 Avatar answered Nov 20 '25 07:11

max66



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!