Lua C ++ userdata矩阵访问元素

时间:2015-09-17 23:22:18

标签: c++ lua lua-api meta-method

我在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]是元素第一行和第二列。

1 个答案:

答案 0 :(得分:1)

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

语法

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

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

语义

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

所以你可以轻松地让m(1,2)返回正确的整数,但如果你想写m(1,2) = 5,那就更难了,因为m(1,2)只返回一个副本,而不是参考

在Java中,(备受诟病的)解决方案是使用Boxing,在其中将基本类型包装在类中,以便为其提供正确的(引用)语义。这里的模拟是你不会返回一个int,你返回一个用户数据,它包含对矩阵中int的引用。

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

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

选项

所以,选项(1)是,为你拥有的任何类型实现某种拳击,并使用__call元方法。

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

选项(3)是,尝试使用不同的语法m[1][2]。然后你想创建一个代表矩阵行的新类,并通过m[1]将它暴露给lua。然而,这也增加了一些复杂性,有很多原因你不想这样做。 (你在评论中表示你并不是真的想这样做。)

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

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