Прокси класса матрицы для ошибки оператора []


Итак, у меня есть такие классы: Matrix и Matrix_Proxy. Оба должны проверить, является ли диапазон допустимым, но здесь я сказал, что это не проблема.

Пока объекты не являются постоянными, это нормально, но так не пойдет. Отправка параметров функции по const& является эффективной практикой, и поэтому здесь она терпит неудачу.

Код (упрощенный):

#include <vector>
#include <cstdlib>
#include <iostream>

template <typename T>
class Matrix_Proxy
{
public:
    Matrix_Proxy(std::vector<T>& _ref, size_t _size) : ref(_ref), size(_size)
    {}
    T& operator[](int i)
    {
        return ref[i];
    }

    const T& operator[](int i) const
    {
        return ref[i];
    }

private:
    std::vector<T>& ref;
    size_t size;

};

template <typename T>
class Matrix
{
public:
    Matrix(size_t x) : values(x), size(x)
    {
        for(auto&& y : values)
        {
            y.resize(x);
            for(auto&& x : y)
                x = 0;
        }
    }

    Matrix_Proxy<T> operator [] (int i)
    {
        return Matrix_Proxy<T>(values[i],size);
    }

    const Matrix_Proxy<T> operator [] (int i) const
    {
        return Matrix_Proxy<T>(values[i],size);
    }

private:
    std::vector<std::vector<T>> values;
    size_t size;
};

int main()
{
    Matrix<int> intMat(5);                    //FINE
    std::cout << intMat[2][2] << std::endl;   //FINE

    const Matrix<int> cintMat(5);             //FINE
    std::cout << cintMat[2][2] << std::endl;  //ERROR

    _Exit(EXIT_SUCCESS);
}

Ошибка:

no matching function for call to 'Matrix_Proxy<int>::Matrix_Proxy(const value_type&, const size_t&)'
         return Matrix_Proxy<T>(values[i],size);
                                              ^

Любые идеи, как решить это?

1 2

1 ответ:

Основная причина проблемы заключается в том, что ваш прокси-сервер допускает неконстантный доступ, даже если сам прокси-сервер был создан с помощью оператора const. Другими словами, ваш код, если бы он мог компилироваться, допускал бы следующее:

const Matrix<int> cintMat(5);
cintMat[2][2] = 2; // Does not compile

Это происходит потому, что Matrix_Proxy, произведенное из operator [] const, имеет как operator [] const, так и operator [] неконст. Ваш Matrix_Proxy понятия не имеет, что он был создан с помощью оператора const!

Чтобы устранить эту проблему, введите другой прокси-сервер и верните его из оператора const []:

template <typename T>
class Matrix_Proxy_Const
{
public:
    Matrix_Proxy_Const(const std::vector<T>& _ref, size_t _size) : ref(_ref), size(_size)
    {}
    const T& operator[](int i) const {
        return ref[i];
    }
private:
    const std::vector<T>& ref;
    size_t size;
};

В классе Matrix измените реализацию оператора const:

const Matrix_Proxy_Const<T> operator [] (int i) const {
    return Matrix_Proxy_Const<T>(values[i],size);
}

Демо.