I want to design a Matrix
class which allows to specify the method of memory management, i.e.
Matrix<Allocator::vector, int> mv(2, 2);
Matrix<Allocator::unique_pointer, int> mu(2, 2);
mv(1, 1) = 1;
mu(1, 2) = 1;
and with mv
and mu
being compatible to each other (i.e. when I overload the "+" operator) despite different memory strategies.
I found already very good help from Class template specializations with shared functionality which does the same for an n dimensional vector class.
using dim_t = std::pair<size_t, size_t>;
enum class Allocator { vector, raw_pointer, unique_pointer };
template <typename T>
class MatrixBase {
public:
MatrixBase() : MatrixBase(0, 0){};
MatrixBase(size_t m, size_t n) : dim_(m, n){};
size_t rows() const;
virtual T& at(size_t i, size_t j);
private:
dim_t dim_;
};
template <typename T>
size_t MatrixBase<T>::rows() const {
return dim().first;
}
template <Allocator A, typename T>
class Matrix : public MatrixBase<T> {};
template <typename T>
class Matrix<Allocator::vector, T> : public MatrixBase<T> {
private:
std::vector<T> data_;
};
template <typename T>
T& Matrix<Allocator::vector, T>::at(size_t i, size_t j) {
return data_[i * rows() + j];
}
template <typename T>
class Matrix<Allocator::unique_pointer, T> : public MatrixBase<T> {
private:
std::unique_ptr<T[]> data_;
};
template <typename T>
T& Matrix<Allocator::unique_pointer, T>::at(size_t i, size_t j) {
return data_[i * rows() + j];
}
Unfortunately the compiler complains
./matrix.hpp:100:34: error: out-of-line definition of 'at' does not match any declaration in 'Matrix<linalg::Allocator::vector,
type-parameter-0-0>'
T& Matrix<Allocator::vector, T>::at(size_t i, size_t j) {
^
./matrix.hpp:103:20: error: use of undeclared identifier 'rows'
return data_[i * rows() + j];
I assume the error originates from
template <typename T>
class Matrix<Allocator::vector, T> : public MatrixBase<T> {
private:
std::vector<T> data_;
};
How do I fix this?