继承并存储静态类信息

发布于 2024-09-06 08:34:23 字数 1234 浏览 0 评论 0原文

我正在尝试用 Lua 设置一些东西,但是 Lua 的细节对于我的问题并不重要。

我希望能够做的是调用一个函数,例如 OpenLib(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'

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

I'm trying to set up some stuff with Lua, but the specifics of Lua aren't important for my question.

What I would like to be able to do is call a function, say OpenLib<T>(L), and have it get the table name for a particular class (as well as it's table) and register it with Lua. It essentially boils down to this:

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

I've tried this a few different ways and I can't get it to work right. I tried making a base class that contains myTable and myTableName like so:

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

Then I could just inherit from LuaInfo, and then fill in the info that I needed. That didn't work because all classes that inherit from LuaInfo would get the same info, so I looked around and got the idea of doing this:

template <class t>
class LuaInfo
// ...

Which made the syntax to initialize it a little silly as I now have to do class Widget : public LuaInfo, but it was closer to working.

template <class T>
void OpenLib(lua_State* L)
{
    if (T::myTable && T::myTableName)
    {
        luaL_openlib(L, LuaInfo<T>::myTableName, LuaInfo<T>::myTable, 0);
    }
}

I've tried a few variants of this to try to get it right but I keep getting errors like

undefined reference to `ag::LuaInfo<ag::ui::Widget>::myTable'

Is what I want to do possible, and if so, whats the right way to go about doing it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

如日中天 2024-09-13 08:34:23

使用

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

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

Using

template<typename T>
class LuaInfo
{
  static const char* myTableName;
  static lua_reg* myTable;
};

should work OK.

Your problem is that you need to define your static variables.

A single source file containing a bunch of lines like this will solve it

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;

and so on.

You may want to define a macro to make this nicer.

#define LUAINFOIMPL(X) luaL_reg* LuaInfo<X>::myTable=0; const char * LuaInfo<X>::myTableName=0
LUAINFOIMPL( ag::ui::Widget );
LUAINFOIMPL( ag::ui::OtherClass );

However its a bit ugly to scale that way. I was thinking traits style templates might solve this .. but I'm not sure they scale any better.

月光色 2024-09-13 08:34:23

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

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

Your first attempt works fine for me. I guess you just forgot to initialize the static members and got some link errors about that. This is what I did:

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

Now if you want to give other info to OpenLib you have to create a new class like LuaInfo and give that new class as template parameters.

But why do you want this info as a template parameters? IMO, this is much simpler:

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文