c++function-pointersstdlist

Is it possible to have a list of pointers to member functions of one class as a member in another class where these functions will be called?


Let's say we have a class A, which has several setter functions with the identical function signature, like the following code:

class A
{
public:
    void setter1(int whatever)
    {
        // set Something ...
    }
    
    void setter2(int whatever)
    {
        // set Something ...
    }
    
    void setter3(int whatever)
    {
        // set Something ...
    }
};

Another class B has an object of class A. Another class C has an object of B. In C, I try to declare the list of function pointers of A and try to call them through B's object.

Following is the example how I called:

class B
{
public:
    A objectA;
};
    
class C
{
    C()
    {
        for (auto fnc: fncList)
        {
            someFunc();
        }
    }
    
    void someFunc()
    {
        auto setterFnc = fncList .front();
        fncList.pop_front();
        objectB.objectA. // --> here I can't find the right syntax to call the function;
    } 

    std::list<void (A::*)(int)> fncList = {&A::setter1, &A::setter2, A::setter2};
};

Is there any other way to declare the pointer-to-function list so that I can use it from any function of the class A through its object in B from C?


Solution

  • Somewhere inside one of the functions from class B, all these functions of class A will be called one by one.

    Yes it is possible as shown below. You have to have an object or a pointer to an object of your class type for calling the member functions using a pointer to those member functions.

    C++17

    Here you can use std::invoke to use the pointer to member function to make the code more readable.

    #include <functional> 
    #include <list>
    struct A
    {
    
        void setter1(int whatever){}
        void setter2(int whatever){}
        void setter3(int whatever){}
    
    };
    struct B
    {
       std::list<void (A::*)(int)> fncList = {&A::setter1, &A::setter2, &A::setter3};
       //lets add a ctor
       B( A &a, int i)
       {
              for(auto ptr: fncList)
              {
                    std::invoke(ptr, a, i);  //calls each of the setter
              }
             
       }
    };
    

    Demo


    Prior C++17

    Here we replace the call std::invoke(ptr, a, i) with:

    (a.*ptr)(i);
    

    Demo