带有函数指针的函数模板的干净实现

问题描述 投票:2回答:2

我已经设法实现和测试我的函数包装器实现,但是,该接口并不像应有的那样好:

template < typename F, F* f >
void register_function( const char* name )
{
    int (*lf) (lua_State *) = function_wrapper< F, f >;
    register_native_function( lf, name );
}

虽然这可以按预期工作,但是用法需要显式的模板参数:

register_function< decltype(hello), &hello >( "hello" );

显然,第一个参数可以从第一个参数推导出,所以理想情况下,我只想拥有

register_function< &hello >( "hello" );

有可能吗?有没有更整洁的方法?


Update:回答问题,为什么将参数模板化而不是传递参数:

许多活页夹(包括Lua活页夹,因为这是专门为Lua设计的)通过值传递函数:

register_function("hello", &hello);

这确实更具可读性,并且从接口方面更容易实现。但这也意味着该函数的地址需要存储在某个位置。

要将函数绑定到Lua,我们需要它具有以下原型:

int (*lua_CFunction) (lua_State *)

没有其他信息传递,因此这是从Lua调用绑定函数时获得的条目和信息。

如果绑定是在编译时完成的,我们可以在将要从Lua执行的代码中提供单独的功能(通过模板),从而为我们提供与手写绑定相当的性能,特别是如果编译器优化了样板代码。

如果绑定是在运行时完成的,那么我们将无法创建新函数,而需要一个全局函数,该全局函数以某种方式知道应将调用分派到哪个函数。通常,我们根本无法获得信息,但是现有的编译时Lua绑定程序会利用Lua自定义按功能的用户数据或闭包来存储执行所需的其他信息。但是,由于可能会有额外的内存分配和闭包调度,因此与手写绑定相比,这对性能有重大影响。

我在以前的绑定实现中遇到了运行时版本的性能问题(尽管压力很大),最终将压力最大的部分重写为手写绑定,并且考虑到这次我打算这样做lua在实时渲染循环中调用,我想找到一个更接近手写性能的解决方案。

如果将函数作为参数传递,显然我们不能在编译时创建函数绑定。

c++ templates c++11 function-pointers
2个回答
3
投票

对不起,戴夫,你不能那样做。


0
投票

将这个问题的六年年龄添加到标记语言版本中:C ++ 17允许使用占位符声明模板参数。

© www.soinside.com 2019 - 2024. All rights reserved.