3

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

4

1 回答 1

1

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

句法

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

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

语义

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

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

在 Java 中(饱受诟病的)解决方案是使用 Boxing,将原始类型包装在一个类中,以便为其提供正确的(引用)语义。这里的类比是您不返回一个 int,而是返回一个包含对矩阵中的 int 的引用的用户数据。

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

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

选项

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

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

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

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

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

于 2015-09-17T23:28:27.107 回答