2016-04-11 7 views
8
void set_ (const void *data, void (*cb)(EV_P_ ev_watcher *w, int revents)) throw() 
{ 
    this->data = (void *)data; 
    ev_set_cb (static_cast<ev_watcher *>(this), cb); 
} 

// function callback 
template<void (*function)(watcher &w, int)> 
void set (void *data = 0) throw() 
{ 
    set_ (data, function_thunk<function>); 
} 

template<void (*function)(watcher &w, int)> 
static void function_thunk (EV_P_ ev_watcher *w, int revents) 
{ 
    function 
    (*static_cast<watcher *>(w), revents); 
} 

こんにちは、libevはC++ラッパーfunction_thunk

私はlibevはのC++ラッパーのEV ++を使用しています。時間。 私はAPIとして使用する方法を知っていますが、完全に理解していないev ++。hにはこのコードがあります。 次のように私はイベントループでCtrl-Cウォッチャーを設定することができます。

sigint_cbの機能の署名がある
ev::sig signal_watcher(evloop); 
signal_watcher.set<sigint_cb>(); 
signal_watcher.start(SIGINT); 

function_thunkは魔法私のsigint_cb機能をキャストすることができる理由

void sigint_cb(ev::sig &w, int revents) 

誰かが説明することができますが署名する

void (*cb)(EV_P_ ev_watcher *w, int revents) 

このC++ソープはどのようなものですか?おかげさまで

答えて

5

function_thunkは魔法のそれだけで正常にキャストの引数でsigint_cbを呼び出すvoid (*cb)(EV_P_ ev_watcher *w, int revents)sigint_cb署名をキャストしません。

当初から、function_thunkはタイプvoid (*)(watcher &w, int)の関数ポインタでintstantiatedできる関数テンプレートです。 だから、基本的にあなたがどこかにあなたのコード内でfunction_thunk<sigint_cb>を書きますと、コンパイラはこのように見ていることになるfunction_thunkインスタンスを対応する作成します。

void function_thunk (EV_P_ ev_watcher *w, int revents) 
{ 
    sigint_cb(*static_cast<watcher *>(w), revents); 
} 

はまたそうでない場合、あなたの例ではev::sigwatcherが同じ型であることに注意してくださいfunction_thunkのテンプレート引数の控除/置換に失敗しました。

+0

ありがとうございました。だから私はstd :: bindの観点から考えると、function_thunkにsigint_cbを束縛しています。実際にstd :: bindと同じように感じるからです。 – lppier