У меня есть класс матрицы в 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.
Что касается синтаксиса, 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) и привык бы к нему. Хотелось бы увидеть, если кто-то знает улучшение к нему.