c++std-functionmember-functions

Handling std::array of structures with std::function


could you please help me how to handle (initialize, call) std::array of structs of std::function. Code like below:

class A
{
  struct Functions
  {
    std::function<bool()> handler1;
    std::function<bool()> handler2;
  };

  bool foo1();
  bool foo2();
  bool foo3();
  bool foo4();
  std::array<Functions, 2> Func_Arr;
};

I would like to map something like:

Func_Arr[0].hanlder1 = foo1;  
Func_Arr[0].hanlder2 = foo2;  
Func_Arr[1].hanlder1 = foo3;  
Func_Arr[1].hanlder2 = foo4;  

and then call only proper handler

I cannot figure out how to handle it, I mean how to mapp functions foo1 and foo2 to the struct and then call them via Func_Arr.

Tried to compile many times but failed


Solution

  • As pointed out in comments, non-static member functions need an instance of the class to be called.

    A - If the fooX() functions do not actually need an instance the class:

    In that case, the solution would be to either mark the member functions as static or to move them outside of the class.

    B - If the fooX() functions actually need an instance of the class:

    For the example, let's assume you have the following class:

    struct A
    {
        bool foo();
    };
    

    In that case, you can change the handler signature as follows:

    std::function<bool (A*)> handler = &A::foo;
    

    You can call it as follows:

    // Create an instance
    A a;
    
    // Call the handler with the previously created instance
    bool v = handler(&a);
    

    C - Case B but you cannot change the handler's signature

    In that case, you can directly bind the handler to an instance with std::bind() when initializing it:

    // Create an instance
    A a;
    
    // Bind the handler to the previoulsy created instance
    std::function<bool ()> handler = std::bind(&A::foo, &a);
    

    Or alternatively, with a lambda function:

    std::function<bool ()> handler = [&a]() -> bool {return a.foo();};
    

    Note: Of course, in your case, you can directly use this as instance since the handlers array belongs to the class as well and will probably be initialized in the constructor.

    And you can call it with:

    bool v = handler();