我在使用模板参数创建静态包装函数时遇到了一些麻烦。我不想直接传递给函数的包装函数,因为它需要一个特定的签名int (lua_State *)
以便它可以传递到下面的功能:使用特定签名创建C++静态包装函数
lua_pushcfunction(L, function);
(这是正确的,我要去一个自动生成lua包装。)
我的第一个想法是创建一个带有函数指针的模板函数作为非类型的模板参数。
template <void(* f)(void)>
int luaCaller(lua_State * _luaState)
{
f();
return 0;
}
到目前为止,这看起来不错。此函数具有适当的签名,并调用我通过模板参数传入的函数。
&(luaCaller<myFunc>)
当我尝试在另一个函数中包装它时,出现了我的问题。非类型模板参数必须外部链接,因此下面将失败:
void pushFunction(lua_State * _luaState, void(* _f)(void))
{
lua_pushcfunction(_luaState, &(luaCaller<_f>));
}
这是有道理的,因为需要在编译时是已知函数的地址。你不能扔任何指针,并期望编译器知道要创建哪些类。不幸的是,如果我在编译时添加一个函数指针是,它仍然会失败。函数指针的值被复制到_a中,因此_a在编译时仍然在技术上不为人知。正因为如此,我希望下面的工作:
void pushFunction(lua_State * _luaState, void(* const _f)(void))
{
lua_pushcfunction(_luaState, &(luaCaller<_f>));
}
也许
void pushFunction(lua_State * _luaState, void(* & _f)(void))
{
lua_pushcfunction(_luaState, &(luaCaller<_f>));
}
在第一种情况下,由于该值不允许改变,我们知道,如果它是外部它在技术上仍然是外部联系的。在第二种情况下,它被作为参考传入,这意味着它应该有相同的连接,不是?但这些尝试都没有奏效。为什么?不知怎的,是否有可能规避这种情况?我如何干净地自动生成一个调用另一个函数的函数?
仅仅因为一个参数是'const'和你提供一个编译时常量不会使参数成为编译时常数,令人伤心。 –
这对我来说很奇怪。是否因为你可以简单地强制转换为const?想到这一点。 – lowq
是的,这是因为当编译器编译'doCaller'时,它不知道未来会传递给它什么。其他地方可以并且可能通过运行时间变量。编译器绝对没有指示参数是编译时间常量,只有一个指示,即一旦函数开始,您将不会修改该参数。 –