在函数参数化的模板中推导参数类型 [英] Deduce argument type in template parametrized by function

查看:257
本文介绍了在函数参数化的模板中推导参数类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个C框架提供经典的延迟回调执行API:

I have C framework that provides classic deferred callback execution API:

typedef void (*callback_t)(int value_1, int value_2, void* arg);

void schedule(callback_t callback, void* arg);

这里 arg 是用户指定的任意值它将被传递给回调,其他回调参数由框架传递。但实际上只有最后一个参数用于处理程序,它必须从 void * 中显式转换。

Here arg is arbitrary value specified by user that will be passed to the callback and other callback parameters are passed by framework. But really only last argument is used in handlers and it has to be explicitly cast from void*.

思考如何调用回调签名以匹配我得到的这个解决方案的真正的回调签名:

Thinking of how callback signature may be changed to match the real one I got to this solution:

template <typename TArg, void (*Callback)(TArg*)>
void run(TArg* arg)
{
    schedule([](int, int, void* arg)
    {
        Callback((TArg*)arg);
    }, arg);
}

...
void handler(int* arg)  // instead of handler(int, int, void* arg)
{
}

...
run<int, handler>(arg);     // instead of schedule(handler, arg)

这里唯一的问题是回调参数类型必须在运行调用时显式指定。

The only problem here is that callback argument type has to be explicitly specified at run invocation.

有没有办法让编译器推导出这种类型?
理想的执行代码应该只是:

Is there a way to make the compiler to deduce this type? Ideally the execution code should be just:

run<handler>(arg);

有另一个解决方案来初始化问题 - 创建自定义函数对象,并将其作为用户参数传递给native API。然后从 void * 解压缩,执行真正的回调和删除函数对象。但是,当没有执行回调时,动作取消有问题。

There is another solution to initial problem - to create custom function object and pass it as user argument to native API. Then unpack it from void*, execute real callback and delete function object. But there are issues with action cancelling when callback is not executed. It will require much more work to be implemented correctly and I prefer to ignore it if there is a more simple way.

推荐答案

每一个都需要更多的工作才能正确实现,我宁愿忽略它。一次在预处理器实际上可以派上用场:

Every once in a while the Preprocessor actually can come in handy:

#define myRun(fun, arg) (::run<::std::remove_pointer_t<decltype(arg)>, fun>(arg))

这将不会多次评估 arg fun

Note that this will not evaluate arg or fun multiple times. The result is also a parenthesized expression (and not something more icky like a declaration) and thus behaves just like an ordinary function call.

这篇关于在函数参数化的模板中推导参数类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆