4

私はそのようなリクエストハンドラーを持つhttpサーバーを持っています:

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

私はそのようなAPIを提供するラッパーを書き込もうとしています:

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

どちらかにhandlerなることができます:

  1. 機能 :bool handleFooBarRequest(const RequestObject& request, ResponseRequest& response);
  2. 既存のオブジェクトのメソッド:FooResourceInstance+bool FooResource::handleFooBarRequest(const RequestObject& request, ResponseRequest& response);
  3. オブジェクトの静的メソッド:static bool FooResource::handleFooBarRequest(const RequestObject& request, ResponseRequest& response);

私は主張します:C ++ 03(gcc 4.1.2)そしてブーストなし(理由はポイントではありません)

これまでのところ、私が見つけた手法では、Boost、C ++ 11、またはサードパーティのコード(http://www.codeproject.com/Articles/136799/Lightweight-Generic-C-Callbacks-or-Yet-Another-Del )を使用しています。 )。

4

2 に答える 2

3

インターフェイスと派生テンプレートクラスを使用します。この手法は「型消去」と呼ばれます。

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);

auto_ptrの代わりにshared_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);
于 2013-02-01T10:04:19.437 に答える
1

ここで説明するこのソリューションは完全に機能します:http://www.codeproject.com/Articles/11015/The-Impossibly-Fast-C-Delegates

ヘッダーは3つだけです。

C ++ 03、gcc 4.1.2 OK、ブーストなし; MITライセンス

于 2013-02-04T12:29:31.273 に答える