假设我有一个C函数
typedef void (* callback_t)(void* data);
status_you_dont_care_about register_callback(callback_t callback, void* data);
我想传递一个lambda作为回调。
什么是惯用的方式...
正如评论者指出的那样,lambda隐式转换为适当类型的函数指针,因此我们可以写:
auto my_lambda = [](void* data) { /* do stuff here */};
register_callback(my_lambda, get_pointer_to_data());
这将编译。不要忘记检查返回值:-)
这就是我现在正在做的事情,但我怀疑它是次优的。
首先,我确保lambda捕获它需要的所有内容,以便它本身可以不带参数调用(因此它实际上不需要像回调那样使用void*
)。然后我使用这段代码:
template <typename Invokable>
void callback_adapter(void *invokable_on_heap)
{
auto retyped_callback = std::unique_ptr<Invokable>{
reinterpret_cast<Invokable*>(invokable_on_heap)
};
(*retyped_callback)(std::forward<Ts>(parameters)...);
// Note: invokable_on_heap will be delete'd
}
template <typename Invokable>
void register_invokable_as_callback(Invokable callback_) {
Invokable* invokable_on_the_heap = new Invokable(std::move(callback_));
register_callback(&callback_adapter<Invokable>, invokable_on_the_heap);
}
注意:使用此方法,回调只能调用一次。它可以适应需要多次调用的回调的情况,在取消注册/销毁任何回调被调用时取消分配。