我有一个 http 服务器,它有一个像这样的请求处理程序:
bool handleRequest(const RequestObject& request, ResponseRequest& response);
我正在尝试编写一个包装器来提供这样的 API:
addRouteHandler(GET, "/foo/bar", handler);
使用 handler
可以是:
- 一个函数:
bool handleFooBarRequest(const RequestObject& request, ResponseRequest& response);
- 现有对象的方法:
FooResourceInstance
+bool FooResource::handleFooBarRequest(const RequestObject& request, ResponseRequest& response);
- 一个对象的静态方法:
static bool FooResource::handleFooBarRequest(const RequestObject& request, ResponseRequest& response);
我坚持:C++03 (gcc 4.1.2) 并且没有 Boost(原因不是重点)
到目前为止,我发现的技术使用 Boost、C++11 或第三方代码 (http://www.codeproject.com/Articles/136799/Lightweight-Generic-C-Callbacks-or-Yet-Another-Del)
最佳答案
使用接口(interface)和派生模板类。这种技术称为“类型删除”。
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);
你可能想使用 shared_ptr 或类似的而不是 auto_ptr,这完全取决于你想如何存储这些对象。
编辑: 您可以编写自己的成员函数包装器/闭包/函数对象。代码看起来像下面这样(我还没有尝试编译它,所以可能会出现一些错误):
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);
关于c++ - 如何在没有boost的情况下在C++03中实现一个通用的回调机制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14643581/