0

我正在尝试用 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
// ...

这使得初始化它的语法有点傻,因为我现在必须做 class 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'

我想做的事情是否可能,如果是,那么正确的方法是什么?

4

2 回答 2

1

使用

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 );

然而,以这种方式扩展它有点难看。我在想特征样式模板可能会解决这个问题..但我不确定它们是否能更好地扩展。

于 2010-06-23T08:27:55.543 回答
0

你的第一次尝试对我来说很好。我猜你只是忘记初始化静态成员并得到一些链接错误。这就是我所做的:

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);
    }
}

class LuaInfo
{
    public:
        static const char* myTableName;
        static luaL_reg* myTable;
};

//init static members
const char*  LuaInfo::myTableName = 0;
luaL_reg* LuaInfo::myTable = 0;

int main()
{
    OpenLib<LuaInfo>(0);
}

现在,如果您想提供其他信息,OpenLib则必须创建一个新类LuaInfo,并将该新类作为模板参数。

但是为什么要将此信息作为模板参数呢?IMO,这要简单得多:

struct LuaInfo
{
    const char* myTableName;
    luaL_reg* myTable;
};

static void OpenLib(lua_State* L, LuaInfo info)
{
    // this func does some other stuff too that I'm omitting, important bit below
    if (info.myTable && info.myTableName)
    {
        luaL_openlib(L, info.myTableName, info.myTable, 0);
    }
}

int main()
{
    LuaInfo info = {/*some values here*/};
    OpenLib(0, info);
}
于 2010-06-23T07:47:17.037 回答