Прокси класса матрицы для ошибки оператора []
Итак, у меня есть такие классы: 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 ответ:
Основная причина проблемы заключается в том, что ваш прокси-сервер допускает неконстантный доступ, даже если сам прокси-сервер был создан с помощью оператора
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); }