Lua C ++ матрица пользовательских данных доступа к элементам

У меня есть класс матрицы в 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] — элемент в первой строке и второй столбец

3

Решение

Есть две основные проблемы. синтаксис lua и семантика lua.

Синтаксис

Что касается синтаксиса, m(1,2) безусловно, возможно, если вы используете __call метаметод пользовательских данных.

Я не думаю что m[1,2] Возможно, я думаю, что не может быть действительным Луа. Ты можешь использовать m[{1,2}] если вы используете __index метаметод хотя.

Семантика

Основная проблема заключается в том, что lua, как и javascript, java и другие языки, отличные от C ++, делает примитивные целые числа типами значений, а не ссылочными типами.

Так что вы можете легко сделать m(1,2) верните правильное целое число, но если вы хотите написать m(1,2) = 5Сложнее, потому что m(1,2) возвращает только копию, а не ссылку.

В Java (очень клеветническое) решение состоит в том, чтобы использовать Boxing, где вы оборачиваете примитивный тип в класс, чтобы дать ему правильную (ссылочную) семантику. Аналогом здесь будет то, что вы не возвращаете int, вы возвращаете userdata, который оборачивает ссылку на int в вашей матрице.

В Луа вы обычно избегаете этого, используя __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], Затем вы захотите создать новый класс, представляющий строку матрицы, и сделать его доступным для lua через m[1], Однако это также добавляет некоторую сложность, есть различные причины, по которым вы бы не хотели этого делать. (И вы указали в комментариях, что вы действительно не хотите этого делать.)

Самое приятное было бы, если бы они расширили язык Луа так, чтобы m[1,2] был просто синтаксический сахар для m[{1,2}] или что-то типа того. Но я бы не стал задерживать дыхание.

Если бы это был я, и вариант (3) исключен, я бы выбрал вариант (2) и привык бы к нему. Хотелось бы увидеть, если кто-то знает улучшение к нему.

1

Другие решения


По вопросам рекламы [email protected]