I have a class called "Tasks" that needs to store methods from other classes, and be able to execute them. I'd like it to work like this:
Window *window = new Window();
Tasks* tasks = new Tasks();
tasks.m_tasks.Add(window.Create("My Window"));
Then I could call that window creation from my tasks class, by iterating over the stored tasks and executing each one:
tasks.ExecuteTasks();
What would be the datastructure of "m_tasks" that stores the functions, and how could I call them?
I would use a std::list<std::function<void()> >, or boost::function if std::function is not available.
And you'll need to change the syntax of that Add call to avoid executing the Create method right away.
C++11:
class Tasks {
public:
void Add(const std::function<void()>& f)
{ callbacks_.push_back( f ); }
void Add(std::function<void()>&& f)
{ callbacks_.emplace_back( std::move( f ) ); }
// ...
private:
std::list<std::function<void()> > callbacks_;
};
int main() {
Window window;
// ...
tasks.Add( [&]() { window.Create("My Window"); } );
// ...
}
C++03:
class Tasks {
public:
void Add(const boost::function<void()>& f)
{ callbacks_.push_back( f ); }
private:
std::list<boost::function<void()> > callbacks_;
};
int main() {
// ...
tasks.Add( boost::bind( &Window::Create, boost::ref(window), "My Window" ) );
// ...
}
You could use a list of tr1 or boost ::functions as #aschepler says, but this scenario is perfect for boost::signals.
class Tasks {
boost::signal<void ()> m_tasks;
};
// ...
tasks.m_tasks.connect(&someFunction);
// ExecuteTasks:
tasks.m_tasks();
This allows for a lot of extra functionality, like handling arguments, returns, and letting clients disconnect their tasks if they want to.
You'll need slightly complicated structure for this:
class Task
{
public:
virtual void Execute()=0;
};
template<class T, class R, class P1>
class Function1 : public Task
{
public:
Function1(T *ptr, R (T::*fptr)(P1), P1 p1) : ptr(ptr), fptr(fptr),p1(p1) { }
void Execute() { (ptr->*fptr)(p1); }
private:
T *ptr;
R (T::*fptr)(P1);
P1 p1;
};
std::vector<Task*> vec;
This is relatively straightforward if you know what the arguments will be. You could use a function pointer, with some extras to make it a 'method' pointer. See:
http://mdzahidh.wordpress.com/2008/07/16/pointer-to-c-class-methods-or-should-you-call-em-method-pointers/
However, this would not allow you to pass arbitrary arguments. You might be able to do it with C++ templates, but it would be nasty hackery. I would strongly advise avoiding this and going with traditional function/method pointers if at all possible.
m_tasks is going to be a collection of some sort, I'd probably use a list unless you need to be able to add/remove in the middle. The thing you will be storing in the list is a function pointer. That is, a pointer to a function. With the straightforward version of the code I have below, you cannot have generic function pointers, you must be specific about the parameter types and the return value type. It might be possible to use templates to break this restriction. I don't know off the top of my head.
// define FunctionPtr as a pointer to a function that takes a single char* param and returns void
typedef void(*FunctionPtr)(char*);
// define an stl:list of FunctionPtr items
std:list<FunctionPtr> m_tasks;
Related
I am trying to generalize a callback mechanism.
I need two things for that:
Calling it in a general matter: void call() - that I was able to manage
I mean that everyone can get a void call() function, and I can even (easily) store them in an array. They are all of the same type.
class Function{
public:
virtual void call()=0;
};
template<typename T>
class TemplatedFunction : public Function{
public:
int (T::*m_fkt)();
T* m_obj;
TemplatedFunction(T* obj, int (T::*fkt)()):m_fkt(fkt),m_obj(obj){}
// Can also set here a [&](){ f(Args...args) } that will capture the callback arguments, and call it via call(). f being the std::function created for the callback.
void call(){
(m_obj->*m_fkt)();
}
};
Set (register callback) in a general matter: here I got lost...
My callbacks are statically allocated.
I saw this great option, but my only option is using a capturing lambda.
( no bind, or tuple.. )
This option is great as I can store an array of EventHandler that basically will differ by the ID of a message I will get. Unfortunately I can't use new. (I use an in place static allocation for lambda)
class EventHandler{
public:
Function* m_func=nullptr;
template<class T>
void SetCallbackFunction(T* obj, void (T::*mem_fkt)()){
if(m_func != nullptr)
delete m_func;
m_func = new TemplatedFunction<T>(obj,mem_fkt); // can't use it.
}
void TestCallback(){
if(m_func != nullptr)
m_func->call();
}
~EventHandler(){
if(m_func != nullptr)
delete m_func;
}
};
As of my callbacks are statically allocated in advanced, containing the option to call, but not to set.
I know that there are many designs available, but I am limited to using a capturing lambda only with an std::function replacement to store it.
My goal is to pass a single type EventHandler to all my messages, without the need to template the messages, so I will be able to store them in a std::array<Msg_t>
here how I want it to look in the end:
// Statically allocated callbacks that have general `void call()`
//Function* m_func_to_run_callback1 = TemplatedFunction<> Callback1();
// Function* m_func_to_run_callback2 = TemplatedFunction<> Callback2();
int main()
{
EventHandler eh, eh1;
Foo foo; // some class
Foo2 foo2; // some other class
eh.SetCallbackFunction(&foo, &Foo::bar, m_func_to_run_callback1 ) ;
eh1.SetCallbackFunction(&foo2, &Foo2::bar2, m_func_to_run_callback1) ;
return 0;
}
I think that what I am missing is :
class Function{
public:
virtual void call()=0;
virtual void set(void*) = 0; // void* being the callback function
};
I am working on an event daemon in C++ that I would like to use member function callbacks. Basically an event queue would collect events which the daemon continuously services. There is a base class Event struct with an ID and all events would derive from it. I would like the methods registered for each event to use the derived event type in their signature.
struct Event
{
unsigned int eventId;
};
struct EventA : public Event
{
unsigned int x;
unsigned int y;
};
// and struct EventB, EventC (use your imagination...)
const unsigned int EVENT_A = 1;
const unsigned int EVENT_B = 2;
const unsigned int EVENT_C = 3;
class Foo
{
public:
void handlerMethod_A(const EventA& e);
void handlerMethod_B(const EventB& e);
};
class Bar
{
public:
void handlerMethod_C(const EventC& e);
};
Then the Daemon would allow these classes to subscribe their member functions using their 'this' pointer.
class EventDaemon
{
public:
void serviceEvents();
template <class CallbackClass, class EventType>
void subscribe(
const unsigned int eventId,
CallbackClass* classInstancePtr,
void (CallbackClass::*funcPtr)(EventType));
private:
Queue<Event*> eventQueue_;
};
So outside this class you could do something like:
EventDaemon* ed = new EventDaemon();
Foo* foo = new Foo();
Bar* bar = new Bar();
ed->subscribe(EVENT_A, foo, Foo::handlerMethod_A);
ed->subscribe(EVENT_B, foo, Foo::handlerMethod_B);
ed->subscribe(EVENT_C, bar, Bar::handlerMethod_C);
And the EventDaemon loop would be along the lines of
void EventDaemon::serviceEvents()
{
while (true)
{
if (eventQueue_.empty())
{
// yield to other threads
}
else
{
// pop an event out of the FIFO queue
Event e* = eventQueue_.pop();
// somehow look up the callback info and use it
classInstancePtr->*funcPtr(reinterpret_cast<?*>(e));
}
}
}
So my question is how I can store the 'this' pointers and member function pointers in some sort of array by event ID. That way I could look up the 'classInstancePtr' and 'funcPtr' by using e->eventId and the event type as well for the reinterpret cast.
You are working too hard. Use boost functions:
http://www.boost.org/doc/libs/1_47_0/doc/html/function.html
These work whether you have a object or not. They will increase your compile time.
Note, whenever you come across these types of questions where you know many people must have had the same problem, there is probably a simple option and, if it is not in the standard library, it is probably in boost.
In response to Nick, I'm constantly throwing boost function objects into vectors and whatnot.
I've found that, while boost function objects can hold object references, having them do so can lead to bugs with object lifetimes and it is better to have them hold copies of the class objects (you run into the same bugs however you try to hold a reference to a object instance that you don't necessarily control the lifetime of). The pattern:
class Foo
{
struct Member
{
// member variable definitions
};
shared_ptr<Member> m_; // the only real member variable
public:
// etc. including the all-important copy
// constructor and assignment operator and
// don't forget the member function that gets stuck into
// the boost function as a callback!
};
where all the member variables get held in a shared_ptr allows for good performance and you don't have to worry about lifetimes of objects held by function objects because you can copy them by value. Threaded code (what I always seem to be writing nowadays) needs additional things like at least one boost mutex element in Member or some other way to assure values don't get stomped on.
boost::function [or, if your system supports it, std::function] will take care of holding the this pointer quite well, with the added benefit of not requiring an actual object if it isn't necessary. So instead of void (SomeType::*)(EventA) you have std::function<void(EventA)>, and you call std::bind as appropriate.
subscribe(EVENT_A, std::bind(&foo::handleEventA, &foo, std::placeholders::_1));
A trivial wrapper function can be used to provide the same signature as you originally proposed and hide the nasty placeholders.
You do, of course, still have the issue of each event type having its own signature, and the need to ensure you use the correct Event ID code. In both cases, your base Event type can help out. Your callback need not accept an EventA&; it can accept an Event&, and dynamic_cast it to an EventA at runtime. For the ID, query the type directly.
struct Event {
virtual void ~Event() { }
virtual int ID() =0;
};
template<typename E>
struct EventHelper : Event {
virtual int ID() { return E::EventID; }
};
struct EventA : EventHelper<EventA> {
static const int EventID = 89;
};
Now, if you have an Event* object [when you go to dispatch your events], you can do p->ID() to get the appropriate ID, and if you have a EventA type [when you register your callbacks] you can do EventA::EventID.
So now, all you have to store is a std::function<void(const Event&)> and an associated int value for each of your callbacks, no matter what the actual type of event you have.
void subscribe(int id, std::function<void(const Event&)> f) {
callbacks.insert(std::make_pair(id, f));
}
template<typename E>
void subscribe(std::function<void(const Event&)> f) {
subscribe(E::EventID, f);
}
template<typename O, typename E>
void subscribe(O* p, void (O::*f)(const Event&)) {
subscribe<E>(std::bind(f, p, std::placeholders::_1));
}
You still have the issue that user error when subscribing can result in a function being called incorrectly. If you've used dynamic_cast correctly within the callback, this will get caught at runtime, but a compile time check would be nice. So what if we automate that dynamic_cast? For this step, I'm going to use c++11 lambdas, but it can be implemented in C++03 as well using a variety of methods.
template <class CallbackClass, class EventType>
void subscribe(CallbackClass* classInstancePtr, void (CallbackClass::*funcPtr)(EventType)) {
subscribe<EventType::EventID>([&](const Event& e) {
(classInstancePtr->*funcPtr)(dynamic_cast<const EventType&>(e));
});
}
So now we've gone full circle back to your original interface where your callbacks accept the actual type they are going to be working on, but internally you've squeezed them all into a common signature.
Okay, so I finished an implementation of my original desired interface. I was looking through Dennis' answer but eventually got lead to functors and I realized what I was looking for was a simple polymorphic solution. I failed to grasp before that I could create a non-templated base class with which to use for storing templated classes in vectors/arrays. I think this is what mheyman was trying to tell me... so I apologize I didn't get it right away. Just to clarify though I was really looking for the implementation solution for my own benefit and knowledge, not just a 3rd party library to get the job done. So I guess I would be looking for how Boost functions work, not just that they exist and are awesome.
If anyone is still interested here are the important parts of what I ended up with (minus some extraneous stuff and error checking):
EventFunctor is basically a pointer to member function template class
EventFunctorBase is the non-templated base class used to store them in a vector
The Event is dynamic cast using the templated type before being used to invoke the callback
class EventDaemon
{
public:
template <class CallbackClass, class EventType>
void subscribe(
const EventId eventId,
CallbackClass* callbackClassInstancePtr,
void (CallbackClass::*funcPtr)(const EventType&));
private:
EventFunctorBase* callbacks_[MAX_NUM_EVENTS];
};
template <class CallbackClass, class EventType>
void EventDaemon::subscribe(
const EventId eventId,
CallbackClass* callbackClassInstancePtr,
void (CallbackClass::*funcPtr)(const EventType&))
{
callbacks_[eventId] = new EventFunctor<CallbackClass,EventType>(callbackClassInstancePtr,funcPtr);
}
class EventFunctorBase
{
public:
EventFunctorBase();
virtual ~EventFunctorBase();
virtual void operator()(const Event& e)=0;
};
template <class CallbackClass, class EventType>
class EventFunctor : public EventFunctorBase
{
public:
EventFunctor(
CallbackClass* callbackClassInstancePtr,
void (CallbackClass::*funcPtr)(const EventType&));
virtual void operator()(const Event& e);
private:
CallbackClass* callbackClassInstancePtr_;
void (CallbackClass::*funcPtr_)(const EventType&);
};
template <class CallbackClass, class EventType>
EventFunctor<CallbackClass,EventType>::EventFunctor(
CallbackClass* callbackClassInstancePtr,
void (CallbackClass::*funcPtr)(const EventType&))
:
callbackClassInstancePtr_(callbackClassInstancePtr),
funcPtr_(funcPtr)
{
}
template <class CallbackClass, class EventType>
/*virtual*/ void EventFunctor<CallbackClass,EventType>::operator()(const Event& e)
{
(callbackClassInstancePtr_->*funcPtr_)(dynamic_cast<const EventType&>(e));
}
EventDaemon loop
while (true_)
{
if (eventQueue_->empty())
{
// yield to other threads
}
else
{
Event* e = eventQueue_.pop();
(*(callbacks_[e->ID]))(*e);
}
}
My final steps here will be to try and remove the need to have the developer define an ID for each event... of course this might end up a new post later this week.
I am trying to create a threadpool that can run functions from unknown classes. I do not wish to have to create non-members as a proxy.
I have managed to create a working pool & workerthread class and a task structure, all of these are templates.
// ThreadPool.h
/* Threadpool creates N WorkerThreads (each worker has a ptr to the creating pool),
these block until a task is ready then call ThreadPool::doTask() */
template<class T>
struct Task {
Task() : func(0), inst(0) { }
Task(boost::function<void(T*)> function, T* instance) : func(0), inst(0) {
func = function;
inst = instance;
}
void operator()() {
Task::func(inst);
}
T* inst;
boost::function<void(T*)> func;
};
template<class T>
class ThreadPool {
template<class T> friend class WorkerThread;
public:
void addTask(Task<T> task) {
... // Some stuff
}
bool doTask() {
Task<T> task;
... // Gets a task from std::queue
// Check the task actually exists!
if(task.func && task.inst) {
// Do the task
(task)();
}
}
private:
std::queue<Task<T>> mTasks;
};
As is, this code works, providing I determine the class for ThreadPool and Task. But I want to be able to call members of unknown class types. I had considered a void ptr but I could not find a way to convert this to a valid instance ptr. I have also looked into boost::mem_fun but struggled to really get to grips with it.
I have briefly read about C++0x and from what I understand, it should make solving my problem easier but I would like to solve this before then, if at all possible.
Why use a T* at all, instead of just boost::function<void ()>?
That way you can use free functions as well as member functions, and you can simplify your code.
A task for a member on an instance of class X could be queued like this:
poll.add(boost::bind(&X::member, x_instance, other_arguments));
With no casts and no templates in your code.
Update:
Use boost::function instead of your Task class. You then just need to keep track of the instances and call them as appropriate. For example:
class TaskQueue {
std::deque<boost::function<void ()> > m_tasks;
public:
void add(boost::function<void ()> const& f) { m_tasks.push_back(f); }
bool has_task() const { return !m_tasks.empty(); }
void do_task() {
m_tasks.front()();
m_tasks.pop_front();
}
};
int example_enqueue(TaskQueue* tq) {
boost::shared_ptr<RandomClass> rc(new RandomClass);
tq->add(boost::bind(&RandomClass::method, rc, arg_1, arg_whatever));
}
Note that by combining this method with boost::shared_ptr, you get automatic destruction of your objects when the function goes out of scope, if it's the last reference. That makes life a lot easier.
A void* would work. You just have to do a strong reinterpret_cast. But I would not use this solution. Boost has a bunch of ways of creating functor objects: http://www.boost.org/doc/libs/1_46_1/doc/html/function.html
Okay, I'm using SDL with C++ and I started working on a simple GUI for my Map Editor. From a working prototype of a single button, I wrote a generic GUIObject class and a generic Button class. But I have a problem now, In order for the class to be reusable, I need to be able to set for each button what function it calls (i.e. Help! opens the help window, Open opens the file dialog box, they are the same Button class, but they execute different functions).
Now, I used some time ago a simple library for Ruby GUI, and it's syntax used something that was notated there as a "block operator":
Example:
#login_button = Button.new(#window, 98, 131, Network_Data::LOGIN_BUTTON){execute_login}
The last part {} was the thing where you put your own function and the class somehow extracted that and executed that function when clicked. I also heard Java has something similar:
onClick = new Function() { }
So how would I go and implement this in a C++ program (which uses SDL libraries). I don't want to use any GUI libraries because they seem too complicated and I would have a hard time inserting those libraries in my already built code.
You can do it using function/functor/method pointers. (functions should be enough and relatively simple)
you can pass a pointer to the callback function in you button constructor.
Here is a basic example using function pointers.
class Button
{
typedef void(*eventFunction)();
Button( eventFunction funcPtr ) : m_funcPtr( funcPtr ){}
///< A constructor.
/// #param funcPtr The function pointer to register.
~Button(){ m_funcPtr = NULL; }
///< A destructor.
void operator() () const
{
(m_funcPtr)();
}
///< Invokes the registered function.
private:
eventFunction m_funcPtr;
};
And you can use it this way:
void myFunction1() { /* do something */ }
void myFunction2() { /* do something else */ }
Button myButton1( &myFunction1 );
myButton1(); // invoke the function registered
Button myButton2( &myFunction2 );
myButton2(); // invoke the function registered
Here is a more complex example using variadic templates (C++0x)
template < class Tr, class... Args >
class Button
{
typedef Tr(*eventFunction)(Args...);
Button( eventFunction funcPtr ) : m_funcPtr( funcPtr ){}
///< A constructor.
/// #param funcPtr The function pointer to register.
~Button(){ m_funcPtr = NULL; }
///< A destructor.
void operator() ( Args&... args ) const
{
(m_funcPtr)(args...);
}
///< Invokes the registered function with the provided arguments.
/// #param args The arguments to transmit to the invoked function.
private:
eventFunction m_funcPtr;
};
And you can use it this way:
void myFunction1( int, double ) { /* do something */ }
void myFunction2() { /* do something */ }
Button<void, int, double> myButton1( &myFunction1 );
myButton1( 10, 20.5 ); // invoke the function registered with two arguments
Button<void> myButton2( &myFunction2 );
myButton1(); // invoke the function registered without argument
The Tr template can be removed and replaced by void if you never plan to use others functions than functions returning void.
Thus Button<void, int, double> myButton1( &myFunction1 ); would change to Button<int, double> myButton1( &myFunction1 );
and Button<void> myButton2( &myFunction2 ); would change to Button<> myButton2( &myFunction2 );
You can do almost the same thing with methods (you need to register a pointer to the instance of the class to call AND the pointer to the method) and with functors (you need to register a pointer to the instance of the functor to call).
On your demand here is the same class to do it with methods. It's up to you to find a way to make your Button class accept functions, functors and methods at once (think virtual ^^). This is the C++0x version
template < class C, class Tr, class... Args >
class Button
{
typedef Tr(C::*eventMethod)(Args...);
~Button(){}
Button( C& target, eventMethod method ) : m_target(target), m_method(method) {}
///< A constructor.
/// #param target The class member instance used to call the method.
/// #param method The class member method pointer to register.
bool operator () ( Args&... args ) const
{
(m_target.*(m_method))(args...);
}
///< Invokes the registered method with the provided arguments.
/// #param args The arguments to transmit to the invoked method.
private:
eventMethod m_method;
C& m_target;
};
And you can use it this way:
class MyClass
{
void method1(){};
void method2( int, double ){};
};
MyClass myC1;
Button<MyClass, void> myButton1( myC1, &MyClass::method1 );
myButton1(); // invoke the registered method using the registered class instance.
Button<MyClass, void, int, double> myButton2( myC1, &MyClass::method2 );
myButton2( 15, 170.5 ); // invoke the registered method using the registered class instance.
If you need to call it from inside the class the method belong to, use this as target parameter instead of myC1.
There are two approaches. You can use run-time polymorphism (boost::function or std::tr1::function or std::function) or you can use a template.
You will need your button class to call functions specified by its users. I recommend you to take a look at Boost Signals library. That library implements signals and slots approach, has very nice documentation and is very well supported. Also, these links should be useful to get the general idea:
Signals and slots
Observer pattern
Callbacks
Hope it helps. Good luck!
It works in almost the same way in c++ as you'd use in java:
onClick = new ClickFunction;
but then you'd obviously need the following to define necessary classes:
template<class A, class B>
class Function { public: virtual B Map(A a) const=0; };
Function<int, int> *onClick;
class ClickFunction : public Function<int,int>
{
public:
ClickFunction(MyObject &o) : o(o) { }
int Map(int a) const { return 10; }
private:
MyObject &o;
};
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.
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):
It should be &Display::SomeTask
The _1 placeholder makes no sense because that creates an unary function object and:
Display::SomeTask takes no arguments
Action::operator() takes no arguments
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();
};
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.
First, you have to use &Display::SomeTask and give Register a return type, and then it depends on your needs
The wrapper should call SomeTask on *this: Omit _1.
The wrapper should call 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.