Lua C++ 用户数据矩阵访问元素

Lua C++ userdata matrix access to elements

我有一个C++矩阵class,构造函数如下:

template <typename T> CMatrix<T>::CMatrix(unsigned int varrow,unsigned int varcolumn)
{
        //Lets set member variables
        this->m_row=varrow;this->m_column=varcolumn;

        //Create a place holder at heap
        m_matrix=new T[varrow*varcolumn];
        //
        unsigned int i=0;
        //
        //Default matrix All elements are zero

            for(i=0;i<varrow*varcolumn;i++)
            {
                    m_matrix[i]=T();
            }

        //
    }

我实现了如下设置和获取方法:

void SetCellValue(unsigned int row,unsigned int col,T value){ m_matrix[row*m_column+col]=value;}
T& GetCellValue(unsigned int row,unsigned int column) const{return m_matrix[row*m_column+column];}

矩阵 class 可从 Lua 访问;但是,我可以从 Lua 访问矩阵元素的唯一方法是,如果 m 是矩阵,m:GetValue 或 m:SetValue。

我想知道是否可以通过符号 m[1,2] 或 m(1,2) 访问(设置)矩阵元素,其中 m 是矩阵,[1,2] 是第一行第二列的元素。

有两个基本问题。 lua 语法和 lua 语义。

语法

就语法而言,如果您使用用户数据的 __call 元方法,m(1,2) 绝对是可能的。

我认为 m[1,2] 不可能,我认为那不可能 lua。如果您使用 __index 元方法,则可以使用 m[{1,2}]

语义

基本问题是 lua,如 javascript、java 和其他非 C++ 语言,使原始整数成为值类型而不是引用类型。

所以你可以很容易地让m(1,2)return成为正确的整数,但是如果你想写m(1,2) = 5,那就更难了,因为m(1,2)只有return是副本,不是参考。

在 Java 中,(饱受诟病的)解决方案是使用装箱,将原始类型包装在 class 中,以便为其提供正确的(参考)语义。这里的类比是你没有 return 一个 int,你 return 一个用户数据,它在你的矩阵中包装了一个对 int 的引用。

在 lua 中,您通常使用 __index__newindex 元方法来避免这种情况。当您从用户数据请求子值时调用 __index,当您分配用户数据的子值时调用 __newindex。所以不需要装箱,你可以给它所有你想要的语义。

问题是在这种情况下,__index__newindex 会给你难看的语法,你必须使用 m[{1,2}]m[{1,2}] = 5 才能得到它以这种方式工作。

选项

因此,选项 (1) 是,为您拥有的任何类型实施某种装箱,并使用 __call 元方法。

选项 (2) 是,只需使用 __index__newindex 并习惯编写 m[{1,2}].

选项 (3) 是,尝试使用不同的语法 m[1][2]。然后你会想要创建一个新的 class 来表示矩阵的一行,并通过 m[1] 将其暴露给 lua。然而,这也增加了一些复杂性,您出于各种原因不想这样做。 (你在评论中表示你真的不想这样做。)

如果他们扩展 lua 语言,那么 m[1,2] 只是 m[{1,2}] 或类似语言的语法糖,那将是最好的事情。但是,我不会屏住呼吸。

如果是我,选项(3)是不可能的,我想我会选择选项(2)并习惯它。想看看是否有人知道对其进行改进。