我使用Lua API覆盖包含为userdata的我自己的C ++对象的元事件。但是,一些元事件可以采用多个参数,可以是userdata或常规值,我可以将其转换为userdata。例如,__ add,__ eq,__ concat等
首先,对于这些元事件,如果我将两个userdata加在一起,那么__add会被调用,并且只调用一次吗?如果我有两个具有不同__add挂钩的不同类型的userdata,这是相关的(尽管它们具有不同的返回结果将是不好的做法)。
其次,对于这样的示例:2 + userdata
而不是userdata + 2
,是否可以保证userdata始终首先显示在堆栈上?这将使我的实现更加直接,除了__index之外,我还没有找到关于元事件详细行为的大量文档。
最后,如果添加多个对象,Lua的行为是什么?从不使用C API的metatables测试,它似乎是PEMDAS订购。即userdata1 + 3 + userdata2 + userdata3 + nonuserdata
,但我没有找到确认这一点的参考。 __add只能在堆栈上调用一次所有参数,调用第一个userdata的__add,还是从一个方向传播创建临时rvalues?
以下是我如何从堆栈中获取__arg的args的示例,如果参数的顺序是有保证的,这很简单。
if (unlikely(lua_gettop(L) != 2))
{
return LUA_FAILURE;
}
Val *v = CheckLuaUserdata(L, 1);
if (unlikely(!v))
{
return LUA_FAILURE;
}
bool allocated = false;
Val *arg2 = lua_mgr->PullLuaValFromGenericArg(L, 2, &allocated);
if (unlikely(!arg2))
{
return LUA_FAILURE;
}
答案 0 :(得分:2)
第一:左边一个。在A + B的情况下,调用A的__add。
第二:不,抱歉。参数按顺序传递(左侧将保持左侧,右侧将保持向右)
http://lua-users.org/wiki/MetatableEvents
最后:我不完全确定。我严重怀疑它会调用所有的__add,我会怀疑它从左向右移动(遵循数学运算的顺序)。它肯定遵循1 + 1/2的操作顺序。