четверг, 8 декабря 2022 г.

Оператор [][] с индексами как в математике

Можно ли определить для объекта индексацию в виде, максимально похожем на математический вариант? Чтобы сначала индекс по горизонтали, затем по вертикали и чтобы отсчет велся с единицы. Да, если определить оператор возвращающий промежуточный прокси-объект.
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
 
// nColumn and nRow counts from 1
 
class Matrix
{
  double* pData;
  size_t nColumns; 
  size_t nRows;
public:
  class MatrixColumn
  {
      Matrix* pMatrix;
      size_t nColumn;
  public:
      MatrixColumn(Matrix* _pMatrix, size_t _nColumn)
          : pMatrix(_pMatrix), nColumn(_nColumn)
      {
      };

      double& operator[](size_t nRow)
      {
        return (*pMatrix)(nColumn, nRow);
      }
  };

  Matrix(size_t _nColumns, size_t _nRows)
  {
    nColumns = _nColumns;
    nRows = _nRows;
    pData = new double[nColumns * nRows];
    memset(pData, 0, sizeof(pData[0]) * nColumns * nRows);
  };
  ~Matrix()
  {
    delete[] pData;
  };
  double& operator()(size_t nColumn, size_t nRow)
  {
    return pData[ ( nRow - 1 ) * nColumns + ( nColumn - 1 ) ];
  };
  MatrixColumn operator[](size_t nColumn)
  {
    return MatrixColumn(this, nColumn);
  }
};
 
int main_func()
{
    Matrix M(3,3);
 
    M[1][1] = 1;
    M[2][2] = 1;
    M[3][3] = 1;
 
    return 0;
};
Здесь на первый индекс возвращается временный объект, и при побращении через индекс к нему он уже делегирует операцию основному объекту.

В реальном коде, разумеется, нужно добавлять проверки на выход за пределы матрицы и соответствующие параллельные const операции. Впрочем, к самой технике промежуточного прокси объекта это не относится.

По быстродействию, конечно, этот вариант будет сильно хуже чем обращение к предопределенному массиву массивов. Потому этот вариант для случая когда читабельность с точки зрения математики важнее.

Комментариев нет:

Отправить комментарий