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);
}
Run Code Online (Sandbox Code Playgroud)
嗨,
我正在使用libev的C++包装器ev ++.ev ++中有这段代码.我知道如何使用API,但不完全理解.我可以在事件循环中设置一个Ctrl-C观察器,如下所示:
ev::sig signal_watcher(evloop);
signal_watcher.set<sigint_cb>();
signal_watcher.start(SIGINT);
Run Code Online (Sandbox Code Playgroud)
其中sigint_cb的函数签名是:
void sigint_cb(ev::sig &w, int revents)
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么function_thunk可以神奇地将我的sigint_cb函数签名转换为
void (*cb)(EV_P_ ev_watcher *w, int revents)
Run Code Online (Sandbox Code Playgroud)
这是什么C++巫术?谢谢.
小智 5
function_thunk并没有神奇地将sigint_cb签名转换为void (*cb)(EV_P_ ev_watcher *w, int revents)它,只需使用正确的转换参数调用sigint_cb.
从一开始,function_thunk是一个函数模板,可以使用类型的函数指针进行解释void (*)(watcher &w, int).所以基本上当你function_thunk<sigint_cb>在代码中编写某个地方时,编译器会创建相应的function_thunk实例,它看起来像这样:
void function_thunk (EV_P_ ev_watcher *w, int revents)
{
sigint_cb(*static_cast<watcher *>(w), revents);
}
Run Code Online (Sandbox Code Playgroud)
另请注意,在您的示例中ev::sig,watcher它们是相同的类型,否则function_thunk的模板参数推断/替换将失败.
| 归档时间: |
|
| 查看次数: |
403 次 |
| 最近记录: |