使用函数指针的函数模板的干净实现 [英] Clean implementation of function template taking function pointer
问题描述
我已经设法实现并测试了函数包装器的实现,但是,该接口并不像应有的那样好:
I've managed to implement and test my function wrapper implementation, however, the interface isn't as nice as it should be:
template < typename F, F* f >
void register_function( const char* name )
{
int (*lf) (lua_State *) = function_wrapper< F, f >;
register_native_function( lf, name );
}
尽管这可以按预期工作,但需要使用显式模板参数:
While this works as expected, the usage requires to explicit template parameters:
register_function< decltype(hello), &hello >( "hello" );
很明显,第一个参数可以从第一个参数中推导出,所以理想情况下,我想
Obviously the first parameter could be deduced from the first one, so ideally I'd like to just have
register_function< &hello >( "hello" );
有可能吗?有没有更整洁的方法?
Is it possible? Is there a neater way to do it?
更新:回答问题,为什么参数化而不是传递的参数:
Update: Answering the question, why is the parameter templated instead of passed:
许多活页夹(包括Lua活页夹,因为这是专门为Lua设计的),按值传递函数:
Many binders (including Lua ones, as this is particularly designed for Lua) pass functions by value:
register_function("hello", &hello);
这确实更具可读性,并且从接口方面更容易实现。但这也意味着该函数的地址需要存储在某个地方。
This is indeed more readable, and from the interface side more easily implementable. But that also means that the adress of the function needs to be stored somewhere.
要将函数绑定到Lua,我们需要它具有以下原型:
To bind a function to Lua we need it to have the following prototype:
int (*lua_CFunction) (lua_State *)
没有传递其他信息,因此这是从Lua调用绑定函数时获得的条目和信息。
No other information is passed, hence this is the entry and information we get when a bound function is called from Lua.
如果绑定是在编译时完成的,我们可以在将要由Lua执行的代码中提供一个单独的函数(按模板),从而使我们的性能相当可观编写的绑定,特别是如果编译器优化了样板代码。
If the binding is done at compile time, we can provide a separate function (by templates) in the code that will be executed from Lua, giving us comparable performance to hand-written bindings, especially if the compiler optimizes away the boilerplate code.
如果绑定是在运行时完成的,那么我们将无法创建新函数,而需要以某种方式创建全局函数知道应该将调用分派到哪个函数。通常,我们根本无法获得信息,但是现有的编译时Lua绑定程序会利用Lua自定义按功能的用户数据或闭包来存储执行所需的其他信息。但是,由于可能需要额外的内存分配和闭包调度,因此与手写绑定相比,这对性能有重大影响。
If the binding is done at runtime, then we cannot create new functions and need a global function that somehow knows what function should it dispatch the call to. Normally, we wouldn't be able to get the information at all, but existing compile-time Lua binders take advantage of Lua custom per-function userdata or closures to store the additional information needed to perform the execution. However, this has a significant performance hit compared to a hand-written binding, because of possible additional memory allocations and closure dispatching.
我遇到了性能问题以前的绑定实现中的运行时版本(尽管压力很大),最终将压力最大的部分重写为手写绑定,并且考虑到这次我打算在实时渲染循环中进行lua调用,找到更接近手写性能的解决方案。
I've had problems with perfomance of the runtime version in a previous binding implementation (although a very stressed one) which ended up in rewriting the most stressed parts into hand-written bindings, and, considering that this time I plan to do the lua calls in a realtime rendering loop, I want to find a solution that will be closer to hand-written performance.
如果我们将函数作为参数传递,则显然无法在编译时创建函数绑定。 / p>
If we pass the function as a parameter, we obviously cannot create the function binding at compile time.
推荐答案
对不起,戴夫,你不能这样做。
I'm sorry Dave, you cannot do that.
已经提出了具有从模板类型列表中的文字类型推导的模板类型的提议。最后我检查了一下,它并不会进入C ++ 1y(又名C ++ 14)。
There have been proposals put forward to have template types that are deduced from literal types later on in the template type list. Last I checked, it wasn't going to get into C++1y (aka C++14).
在该语言添加功能之前,宏可能会有所帮助:
A macro could help until the language adds the feature:
#define REGFUNC( F ) decltype(F), (F)
register_function< REGFUNC(hello) >( "hello" );
也有人在C ++中增加了对 lambda to C function的支持(可以有状态 lambda,并要求它生成一个C函数,该函数将使用该状态调用该函数),但我不知道它的进展情况。
There was also talk of adding "lambda to C function" support in C++ (being able to take a stateful lambda, and asking it to generate a C function that will call it using that state), but I don't know how that is progressing.
这篇关于使用函数指针的函数模板的干净实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!