Не выделяйте динамически в двух измерениях, как это.Это яд для вашего кеша и совершенно бессмысленный .Я вижу это все время и я бы не хотел!Вместо этого сделайте себе std::vector<double>
размера rows*cols
.
В любом случае, уловка, позволяющая [width][height]
, - это прокси-класс .Пусть ваш operator[]
вернет экземпляр класса, который имеет собственный operator[]
для выполнения поиска второго уровня.
Примерно так:
#include <iostream>
#include <vector>
struct Matrix
{
Matrix(const size_t columns, const size_t rows)
: columns(columns)
, rows(rows)
, data(columns*rows, 0)
{}
size_t index(const size_t x, const size_t y) const
{
return x + y*columns;
}
double& at(const size_t x, const size_t y)
{
return data[index(x, y)];
}
double at(const size_t x, const size_t y) const
{
return data[index(x, y)];
}
template <bool Const>
struct LookupHelper
{
using ParentType = std::conditional_t<Const, const Matrix, Matrix>;
using ReturnType = std::conditional_t<Const, double, double&>;
LookupHelper(ParentType& parent, const size_t x) : parent(parent), x(x) {}
ReturnType operator[](const size_t y)
{
return parent.data[parent.index(x, y)];
}
const ReturnType operator[](const size_t y) const
{
return parent.data[parent.index(x, y)];
}
private:
ParentType& parent;
const size_t x;
};
LookupHelper<false> operator[](const size_t x)
{
return {*this, x};
}
LookupHelper<true> operator[](const size_t x) const
{
return {*this, x};
}
private:
const size_t columns, rows;
std::vector<double> data;
};
int main()
{
Matrix m(42, 3);
m[15][3] = 1;
std::cout << m[15][3] << '\n';
}
(Вна самом деле, вы бы хотели сделать его подвижным, и, несомненно, его можно немного привести в порядок.)
Конечно, переключается на operator()
или a .at(width, height)
функция-член намного проще ...