перегрузка операторов c++

Потихоньку разбираюсь с C++. Решил реализовать матрицу используя только "встроенные" возможности C++. Хочу получать значение своей "матрицы" по двум индексам (как-то вот так: m[i][j]). Получилось пока только с помощью круглых скобок (m(i, j)), но это всё равно не то. Пытаюсь найти доступную информация для понимания - не получается. Поэтому обращаюсь к вам. Помогите, пожалуйста.

#include "Matrix.h"


Matrix::Matrix() : size(0), data(new int[0]) {}

Matrix::Matrix(unsigned size)
{
    this->size = size;
    this->data = new int[size * size];
    this->init_data();
}

void Matrix::init_data() 
{
    for (unsigned i = 0; i < this->size * this->size; i++)
        this->data[i] = rand() % 1000;
}

void Matrix::print_matrix()
{
    for (unsigned i = 0; i < this->size; i++)
    {
        for (unsigned j = 0; j < this->size; j++)
        {
            std::cout << std::setw(3) << std::setfill('0') << this->data[i * this->size + j] << ' ';
        }
        std::cout << std::endl;
    }
    std::cout << std::endl;
}

void Matrix::insert_zeros()
{
    for (unsigned i = 0; i < this->size; i++)
    {
        for (unsigned j = 0; j < this->size; j++)
        {
            if (i > j)
                this->data[i * this->size + j] = 0;
        }
    }
}

int& Matrix::operator()(unsigned i, unsigned j)
{   
    return this->data[i * this->size + j];
}


Ответы (1 шт):

Автор решения: HolyBlackCat

У вас уже все нормально сделано (не считая забытой const-перегрузки), нет большого смысла поддерживать другой синтаксис.

Если используете C++23, то можно поменять на m[i, j] (просто поменять operator() на operator[]).

Поддерживать синтаксис [i][j] смысла нет. Но если очень хочется, то нужно делать operator[] с одним аргументом, и возвращать по значению объект вспомогательного класса, у которого тоже перегружен []. Даже не обязательно городить свой класс, потому что он уже есть в стандартной библиотеке - std::span. (Еще можно было бы возвращать просто указатель, но тогда теряем возможность включить проверку границ.)

Получается что-то типа:

std::span<int> operator[](std::size_t i)
{   
    return {data + i * size, size};
}

std::span<const int> operator[](std::size_t i) const
{   
    return {data + i * size, size};
}

Не забываем про правило трех - у вас забыт деструктор, копирующий конструктор и operator= и перемещающий конструктор и operator=.

Еще, какой бы способ перегрузки [] не выбрали, нужно делать две перегрузки: const и не-const.

→ Ссылка