How to implement a generic callback mechanism in C ++ 03 without promotion?

I have an http server that has a request handler:

bool handleRequest(const RequestObject& request, ResponseRequest& response); 

I am trying to write a wrapper that would provide such an API:

 addRouteHandler(GET, "/foo/bar", handler); 

With handler can be either:

  • function: bool handleFooBarRequest(const RequestObject& request, ResponseRequest& response);
  • method for an existing object: FooResourceInstance + bool FooResource::handleFooBarRequest(const RequestObject& request, ResponseRequest& response);
  • static object method: static bool FooResource::handleFooBarRequest(const RequestObject& request, ResponseRequest& response);

I insist: C ++ 03 (gcc 4.1.2) and no Boost (reason is NOT a point)

So far, the methods that I have found use Boost, C ++ 11 or third-party code ( http://www.codeproject.com/Articles/136799/Lightweight-Generic-C-Callbacks-or-Yet-Another-Del )

+4
source share
2 answers

Use the interface and derived template class. This method is called type erasure.

 class CallbackBase { public: virtual ~CallbackBase() = 0; virtual bool exec(const RequestObject& request, ResponseRequest& response) = 0; }; template <typename F> class CallbackImpl : public CallbackBase { public: CallbackImpl(F f) : f_(f) {} virtual bool exec(const RequestObject& request, ResponseRequest& response) { return f_(request, response); } private: F f_; }; template <typename F> void CreateCallback(F f, std::auto_ptr<CallbackBase>& r) { r.reset(new CallbackImpl<F>(f)); } // examples std::auto_ptr<CallbackBase> my_callback; CreateCallback(GlobalFooBarRequest, my_callback); CreateCallback(&FooResource::staticFooBarRequest, my_callback); // for member function, use std::mem_fun and std::bind1st ... my_callback->exec(request, response); 

You might want to use shared_ptr or the like instead of auto_ptr, it all depends on how you want to save these objects.

Edit: you can write your own object-object-wrapper / closure / function object. The code looks something like this (I did not try to compile it so that there might be some errors):

 template <typename T> class RequestWrapper { typedef bool (T::*F)(const RequestObject&, ResponseRequest&); T* obj_; F f_; public: RequestWrapper(T* obj, F f) : obj_(obj) , f_(f) {} bool operator()(const RequestObject& request, ResponseRequest& response) const { return (obj_->*f_)(request, response); } }; template <typename T, typename F> RequestWrapper<T> BindRequestMfn(T* obj, F mfn) { return RequestWrapper<T>(obj, mfn); } CreateCallback(BindRequestMfn(foo, &FooResource::fooBarRequest), my_callback); 
+3
source

This solution, described here, fully works: http://www.codeproject.com/Articles/11015/The-Impossibly-Fast-C-Delegates

Only 3 headings.

C ++ 03, gcc 4.1.2 OK and no Boost; MIT License

+1
source

All Articles