Lua c++ userdata矩阵对元素的访问

Lua C++ userdata matrix access to elements

本文关键字:元素 访问 c++ userdata Lua      更新时间:2023-10-16

我有一个c++中的矩阵类,构造函数如下:

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

我已经实现了set和get方法如下:

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

矩阵类可以从Lua中访问;然而,我可以从Lua访问矩阵元素的唯一方法是,如果m是一个矩阵,m:GetValue或m:SetValue。

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

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

语法

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

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

<<h3>语义/h3>

基本问题是lua,像javascript, java和其他非c++的语言一样,使原始整数成为值类型而不是引用类型。

所以你可以很容易地让m(1,2)返回正确的整数,但如果你想写m(1,2) = 5,这就比较困难了,因为m(1,2)只返回一个副本,而不是引用。

在Java中,(饱受诟病的)解决方案是使用装箱(Boxing),将基本类型包装在类中,以便为其提供正确的(引用)语义。这里的类似情况是,您不返回int,而是返回userdata,该userdata在矩阵中封装了对int的引用。

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

问题是,在这种情况下,__index__newindex会给你丑陋的语法,你必须使用m[{1,2}]m[{1,2}] = 5来让它以这种方式工作。

<<h3>选项/h3>

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

选项(2)是,只用__index__newindex,习惯写m[{1,2}]

选项(3)是,尝试使用不同的语法m[1][2]。然后,您将希望创建一个表示矩阵一行的新类,并通过m[1]将其暴露给lua。然而,这也增加了一些复杂性,有各种理由不希望这样做。(并且您在注释中指出您并不想这样做。)

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

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