简体   繁体   English

如何在没有boost的情况下在C ++ 03中实现通用回调机制?

[英]How to implement a generalized callback mechanism in C++03 without boost?

I have an http server that has a request handler like that : 我有一个http服务器,有一个像这样的请求处理程序:

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

I'm trying to write a wrapper that would provide an API like that : 我正在尝试编写一个提供类似API的包装器:

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

With handler able to be either : handler可以是:

  1. a function : bool handleFooBarRequest(const RequestObject& request, ResponseRequest& response); 一个函数: bool handleFooBarRequest(const RequestObject& request, ResponseRequest& response);
  2. a method on an existing object : FooResourceInstance + bool FooResource::handleFooBarRequest(const RequestObject& request, ResponseRequest& response); 现有对象上的方法: FooResourceInstance + bool FooResource::handleFooBarRequest(const RequestObject& request, ResponseRequest& response);
  3. a static method of an object : static bool FooResource::handleFooBarRequest(const RequestObject& request, ResponseRequest& response); 对象的静态方法: static bool FooResource::handleFooBarRequest(const RequestObject& request, ResponseRequest& response);

I insist : C++03 (gcc 4.1.2) and no Boost (the reason is NOT the point) 我坚持:C ++ 03(gcc 4.1.2)并没有Boost(原因不是重点)

So far the techniques I have found either use Boost, C++11 or third-party code ( http://www.codeproject.com/Articles/136799/Lightweight-Generic-C-Callbacks-or-Yet-Another-Del ) 到目前为止,我发现的技术要么使用Boost,C ++ 11或第三方代码( http://www.codeproject.com/Articles/136799/Lightweight-Generic-C-Callbacks-or-Yet-Another-Del

Use an interface and a derived template class. 使用接口和派生模板类。 This technique 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 a shared_ptr or similar instead of auto_ptr, all depends on how you want to store these objects. 您可能希望使用shared_ptr或类似的而不是auto_ptr,所有这些都取决于您希望如何存储这些对象。

Edit: you can write your own member function wrapper/closure/function object. 编辑:您可以编写自己的成员函数包装器/闭包/函数对象。 Code would looks something like the following (I haven't tried compiling it so there could 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);

This solution described here fully works : http://www.codeproject.com/Articles/11015/The-Impossibly-Fast-C-Delegates 这里描述的解决方案完全有效: http//www.codeproject.com/Articles/11015/The-Impossibly-Fast-C-Delegates

Only 3 headers. 只有3个标题。

C++03, gcc 4.1.2 OK and no Boost ; C ++ 03,gcc 4.1.2 OK,没有Boost; MIT license MIT许可证

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM