2

我正在使用 Lua API 来覆盖我自己的 C++ 对象的元事件,这些对象包装为用户数据。但是,一些元事件可以采用多个参数,这些参数可能是用户数据或常规值,我可以将其转换为用户数据。例如,__add、__eq、__concat 等。

首先,对于这些元事件,如果我将两个用户数据相加,它们的 __add 会被调用,它是否只被调用一次?如果我有两种不同类型的用户数据和不同的 __add 钩子,这是相关的(尽管它们有不同的返回结果是不好的做法)。

其次,对于这样的示例:2 + userdata代替userdata + 2,是否可以保证 userdata 总是首先出现在堆栈上?这将使我的实现更加简单明了,除了 __index 之外,我还没有找到太多关于元事件详细行为的文档。

最后,如果添加多个对象,Lua 的行为是什么?从不使用 C API 的元表测试来看,似乎是 PEMDAS 排序。即 userdata1 + 3 + userdata2 + userdata3 + nonuserdata,但我没有找到证实这一点的参考。__add 是否只使用堆栈上的所有参数调用一次,调用第一个用户数据的 __add,还是从一个方向传播创建临时右值?

这是我如何从 __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;
    }
4

1 回答 1

2

第一:左边。在 A + B 的情况下,调用 A 的 __add。

第二:不,对不起。参数按顺序传递(左保持左,右保持右)

http://lua-users.org/wiki/MetatableEvents

最后:我不完全确定。我严重怀疑它会调用 __add 所有这些,我怀疑它会从左到右移动(遵循数学中的运算顺序)。它当然遵循 1 + 1 / 2 的操作顺序。

于 2016-09-01T17:36:08.687 回答