I wanted to have something like the semantics of a Java interface with C ++. First, I used boost::signal to call back explicitly registered member functions for this event. It worked very well.
But then I decided that some pools of callback functions are connected, and it makes sense to abstract and register them for all callbacks associated with the instance. But I found out that the specific nature of boost::bind and / or the adoption of this seemed to make that break. Or perhaps the fact that the declaration of the add_listener(X &x) method changed the code generated by boost::bind .
I have a very rough understanding of why the problem occurred, and I think that it probably works correctly in accordance with its design. I'm curious: what should I have done instead? Of course, there is the right way to do this.
Here is a sample code:
#include <boost/bind.hpp> #include <boost/function.hpp> #include <iostream> using namespace std; struct X; struct Callback { virtual void add_listener(X &x) = 0; }; struct X { X() {} X(Callback &c) { c.add_listener(*this); } virtual void go() { cout << "\t'" << __PRETTY_FUNCTION__ << "'" << endl; } }; struct CallbackReal : public Callback { virtual void add_listener(X &x) { f = boost::bind<void>(boost::mem_fn(&X::go), x); } void go() { f(); } boost::function<void (void)> f; }; struct Y : public X { Y() {} Y(Callback &c) { c.add_listener(*this); } virtual void go() { cout << "\t'" << __PRETTY_FUNCTION__ << "'" << endl; } }; int main(void) { CallbackReal c_x; CallbackReal c_y; X x(c_x); Y y(c_y); cout << "Should be 'X'" << endl; boost::bind<void>(boost::mem_fn(&X::go), x)(); cout << "Should be 'Y'" << endl; boost::bind<void>(boost::mem_fn(&X::go), y)(); cout << "------------------" << endl; cout << "Should be 'X'" << endl; c_x.go(); cout << "I wish it were 'Y'" << endl; c_y.go(); return 0; }
Well, I did not describe the problem completely. The name is misleading.
Oh man. Bring it down. I obviously did not describe the problem very well, and I think it ultimately comes down to a syntax error. :(
source share