Search code examples
c++pointer-to-member

Can i use C++ function pointers like a C#'s Action?


In C ++, I first encountered function pointers.
I tried to use this to make it similar to Action and Delegate in C #.
However, when declaring a function pointer, it is necessary to specify the type of the class in which the function exists.
ex) void (A :: * F) ();
Can I use a function pointer that can store a member function of any class?

In general, function pointers are used as shown in the code below.

class A {
public:
    void AF() { cout << "A::F" << endl; }
};

class B {
public:
    void(A::*BF)();
};

int main()
{
    A a;
    B b;

    b.BF = &A::AF;
    (a.*b.BF)();

    return 0;
}

I want to use it like the code below.
is this possible?
Or is there something else to replace the function pointer?

class A {
public:
    void AF() { cout << "A::F" << endl; }
};

class B {
public:
    void(* BF)();
};

int main()
{
    A a;
    B b;

    b.BF = a.AF;

    return 0;
}

I solved the question through the answer.
Thanks!

#include <functional>
#include <iostream>

class A {
public:
    void AF() { std::cout << "A::F" << std::endl; }
};

class C {
public:
    void CF() { std::cout << "C::F" << std::endl; }
};

class B {
public:
    B(){}
    std::function<void()> BF;
};

int main() {
    A a;
    C c;
    B b;
    b.BF = std::bind(&A::AF, &a);
    b.BF();
    b.BF = std::bind(&C::CF, &c);
    b.BF();

    int i;
    std::cin >> i;
    return 0;
}

Solution

  • What you want to do is probably something like this. You can use std::function to hold a pointer to a member function bound to a specific instance.

    #include <functional>
    #include <iostream>
    
    class A {
    public:
        void AF() { std::cout << "A::F" << std::endl; }
    };
    
    class B {
    public:
        B(const std::function<void()>& bf) : BF(bf) {}
        std::function<void()> BF;
    };
    
    int main() {
        A a;
        B b1(std::bind(&A::AF, &a)); // using std::bind
        B b2([&a] { a.AF(); });      // using a lambda
    
        b1.BF();
        b2.BF();
    
        return 0;
    }