我正在尝试与Lua建立一些联系,但是Lua的细节对于我的问题并不重要。
我想做的就是调用一个函数,例如OpenLib<T>(L)
,并让它获取特定类(以及它的表)的表名,并在Lua中注册它。本质上可以归结为:
template <class T>
static void OpenLib(lua_State* L)
{
// this func does some other stuff too that I'm omitting, important bit below
if (T::myTable && T::myTableName)
{
luaL_openlib(L, T::myTableName, T::myTable, 0);
}
}
我尝试了几种不同的方法,但无法正常工作。我试图制作一个包含myTable和myTableName的基类,如下所示:
class LuaInfo
{
public:
static const char* myTableName;
static luaL_reg* myTable;
}
然后,我可以从LuaInfo继承,然后填写所需的信息。那是行不通的,因为从LuaInfo继承的所有类都将获得相同的信息,所以我环顾四周,然后想到了这样做:
template <class t>
class LuaInfo
// ...
这使语法的初始化有点傻,因为我现在必须要做Widget类:public LuaInfo,但是它更接近工作了。
template <class T>
void OpenLib(lua_State* L)
{
if (T::myTable && T::myTableName)
{
luaL_openlib(L, LuaInfo<T>::myTableName, LuaInfo<T>::myTable, 0);
}
}
我已经尝试了一些变种以使其正确,但是我不断收到诸如
undefined reference to `ag::LuaInfo<ag::ui::Widget>::myTable'
我想做什么是可能的,如果可以的话,正确的做法是什么?
最佳答案
使用
template<typename T>
class LuaInfo
{
static const char* myTableName;
static lua_reg* myTable;
};
应该工作正常。
您的问题是您需要定义静态变量。
一个包含一堆这样的行的单个源文件将解决该问题
luaL_reg* LuaInfo<ag::ui::Widget>::myTable = 0;
const char * LuaInfo<ag::ui::Widget>::myTableName = 0;
luaL_reg* LuaInfo<ag::ui::OtherClass>::myTable = 0;
const char * LuaInfo<ag::ui::OtherClass>::myTableName = 0;
等等。
您可能想要定义一个宏,以使其变得更好。
#define LUAINFOIMPL(X) luaL_reg* LuaInfo<X>::myTable=0; const char * LuaInfo<X>::myTableName=0
LUAINFOIMPL( ag::ui::Widget );
LUAINFOIMPL( ag::ui::OtherClass );
但是,以这种方式进行缩放有点难看。我以为特质样式模板可以解决此问题..但是我不确定它们的伸缩性是否更好。