Reputation: 6428
class Action {
public:
void operator() () const;
}
class Data {
public:
Data();
~Data();
Register(Action action) { _a = action; }
private:
Action _a;
}
class Display {
public:
Display(Data d) { d.Register( bind(Display::SomeTask, this, _1) ); }
~Display();
void SomeTask();
}
I want to bind the private member _a of Data to a member function of Display, but I get compile errors saying my argument types don't match when I call d.Register, what am I doing wrong? Thanks.
Upvotes: 0
Views: 1436
Reputation: 506925
First, you have to use &Display::SomeTask
and give Register
a return type, and then it depends on your needs
SomeTask
on *this
: Omit _1
. SomeTask
on a passed Display
object: Shift _1
in place of this
. Then, boost::bind
returns some complicated synthesized type that will call the specified function. You need a way to store it, which is where boost::function
comes handy. This is how you can do it
class Display; // forward-declaration
class Data {
public:
Data();
~Data();
template<typename Action>
void Register(Action action) { _a = action; }
private:
boost::function<void(Display&)> _a;
// if wrapper should call it on `*this`
// boost::function<void()> _a;
}
class Display {
public:
// this currently makes no sense. You pass a copy. Probably you
// should consider pass-by-reference or processing "d" further.
Display(Data d) { d.Register( bind(&Display::SomeTask, _1) ); }
// wrapper should call it on `*this`:
// Display(Data d) { d.Register( bind(&Display::SomeTask, this) ); }
~Display();
void SomeTask();
}
Then it should work.
Upvotes: 0
Reputation: 14148
What you're trying to do is not completely clear, but I'll assume that "bind" is boost::bind (or tr1::bind).
A couple of problems with bind(Display::SomeTask, this, _1):
Using Boost.Function and Boost.Bind, here's what you could write to acheive what I guess you're trying to do:
typedef boost::function<void(void)> Action;
class Data {
public:
Data();
~Data();
Register(Action action) { _a = action; }
private:
Action _a;
};
class Display {
public:
Display(Data d) { d.Register( bind(&Display::SomeTask, this) ); }
~Display();
void SomeTask();
};
Upvotes: 4
Reputation: 23624
I cannot see what 'bind' returns, but I absolutely sure this is not compatible with Action class. Also you are using 'copy semantic', so if Action has empty implmentation, you will never get desired. Try change Register(Action* action), and allow 'bind' to return some child of Action class.
Also review possibility to migrate to templates - than you even can exclude Action class at all
template <class A>
class Data { ...
Register(A action)...
A _a;
...
In this case you could be able to use as classes with overridden operator() as functions without argument.
Upvotes: 1