1

I want to implement an object-oriented function pointer in C++ (comparable to delegates in C#).

I wrote an example code which uses "MagicFunctionPainter" as a placeholder for the final class:

class A
{
public: 
    MagicFunctionPointer p;
    void fireEvent()
    {
         p();
    }
};

class B
{
public:
    void init(A* a)
    {
        a->p = &onEvent;
    }
    void onEvent()
    {
        // in a real-world app, it'd modify class variables, call other functions, ...
    }
};

Does std::function or Boost::Signals2 support that? Are there any other librarys that support that case?

Thank you in advance!

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
user3684240
  • 1,420
  • 2
  • 12
  • 18
  • @sehe: If you meant me: This is my one and only StackOverflow account. – user3684240 Dec 03 '14 at 15:02
  • Okay (I usually do mean the person that I address the comment to, yes). That's fine. The correspondence of the questions was just remarkable. Will remove these comments shortly – sehe Dec 03 '14 at 15:22

2 Answers2

2

The type of p should be:

std::function<void(void)> // a function taking no arguments, returning nothing

Create an object of this type in B::init with:

std::bind(&B::onEvent, this);
pmr
  • 58,701
  • 10
  • 113
  • 156
  • I tried `a->p = std::bind(&B::onEvent, this);` but this doesn't compile. My compiler (g++ 4.8.3) returns a few errors: First, a few times `function returning a function` in the `functional` header and a `no match for operator=` in the specified line. – user3684240 Dec 03 '14 at 16:25
  • @user3684240 Can't reproduce and ideone shows a working example: http://ideone.com/yLCUtG Are you sure you didn't accidentally strip away something? Are you matching the signature of `std::function` correctly to the one of the class member function? – pmr Dec 03 '14 at 17:29
  • @user3684240 If you are not binding all arguments of a function, you need to use placeholders: `a->p = std::bind(&B::onEvent, this, std::placeholders::_1);` would be correct. If this seems to complicated a lambda can do the job as well: `a->p = [this](int y) { return this->onEvent(y); };` but contains more syntactic noise IMO. – pmr Dec 03 '14 at 23:44
0

You need to bind it:

 boost::bind(&ClassX::member_function, boost::ref(instance))
sehe
  • 374,641
  • 47
  • 450
  • 633