Шаблон класса с конкретной реализацией и общей функциональностью (CRTP)

bodokaiser спросил: 11 июня 2018 в 11:10 в: c++

Я хочу создать класс Matrix, который позволяет указать способ управления памятью, то есть

Matrix<Allocator::vector, int> mv(2, 2);
Matrix<Allocator::unique_pointer, int> mu(2, 2);mv(1, 1) = 1;
mu(1, 2) = 1;

и mv и mu совместимы друг с другом (т. е. когда я перегружаю оператор "+"), несмотря на различные стратегии памяти.

Я нашел очень хорошую помощь от Специализация шаблонов классов с общей функциональностью , которая делает то же самое для n-мерного векторного класса.

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];
}

К сожалению, компилятор жалуется

./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];

Я предполагаю, что ошибка исходит из

template <typename T>
class Matrix<Allocator::vector, T> : public MatrixBase<T> {
 private:
  std::vector<T> data_;
};

Как это исправить?


0 ответов