hrkz
hrkz

Reputation: 398

CRTP and Expression template Linear algebra

I'm trying to modify my linear algebra module to avoid the virtual vtable things.. Trying to use CRTP and expression template. I went with something basic that should test the whole thing, and I can't get it work.

I have 4 classes, say: The base CRTP class, here Mathbase

template <typename Derived>
class Mathbase
{
 public:
 using T = typename dense_traits<Derived>::T;

  Derived& derived() { return static_cast<Derived&>(*this); }
  const Derived& derived() const { return static_cast<const Derived&>(*this); }

  T& coeff(std::size_t row, std::size_t col) { return derived().coeff(row, col); }
  const T& coeff(std::size_t row, std::size_t col) const { return derived().coeff(row, col); }
  T& coeff(std::size_t index) { return derived().coeff(index); }
  const T& coeff(std::size_t index) const { return derived().coeff(index); }
};

Then, a Densebase in which I implements functions like transpose, determinant, etc:

template <typename Derived>
class Densebase : public Mathbase<Derived>
{
 public:

 using Submat = Subview<Derived, dense_traits<Derived>::M-1, dense_traits<Derived>::N-1>;
 using ConstSubmat = const Subview<const Derived, dense_traits<Derived>::M-1, dense_traits<Derived>::N-1>;

  Submat sub(std::size_t row, std::size_t col) { return Submat(derived(), row, col); }
  ConstSubmat sub(std::size_t row, std::size_t col) const { return ConstSubmat(derived(), row, col); }
};

Note that it declares two types that makes a references on a parent matrix (co-matrix) Then I have the Matrix class, that implements coeff functions by accessing its storage:

template <typename T, std::size_t M, std::size_t N>
class Matrix : public Densebase<Matrix<T,M,N>>
{
  // nothing fancy
};

Now, two things aren't working:

And called like this:

T determinant() const
{
  return det_helper<Derived, dense_traits<Derived>::M>::run(derived());
}

Here is the full code uploaded on PASTEBIN

And the error output as asked:

main.cpp: In instantiation of 'static typename dense_traits<T>::T det_helper<Derived, N>::run(const Densebase<Derived>&) [with Derived = Matrix<float, 3ul, 3ul>; long unsigned int N = 3ul; typename dense_traits<T>::T = float]':
main.cpp:68:62:   required from 'typename Densebase<Derived>::base::T Densebase<Derived>::determinant() const [with Derived = Matrix<float, 3ul, 3ul>; typename Densebase<Derived>::base::T = float]'
main.cpp:159:30:   required from here
main.cpp:33:65: error: no matching function for call to 'det_helper<Matrix<float, 3ul, 3ul>, 3ul>::run(Densebase<Matrix<float, 3ul, 3ul> >::ConstSubmat)'
       det += ((i & 1) ? -1 : 1)*dense.coeff(0,i)*det_helper::run(dense.sub(0,i));
                                                                 ^
main.cpp:28:51: note: candidate: static typename dense_traits<T>::T det_helper<Derived, N>::run(const Densebase<Derived>&) [with Derived = Matrix<float, 3ul, 3ul>; long unsigned int N = 3ul; typename dense_traits<T>::T = float]
   static inline typename dense_traits<Derived>::T run(const Densebase<Derived>& dense)
                                                   ^
main.cpp:28:51: note:   no known conversion for argument 1 from 'Densebase<Matrix<float, 3ul, 3ul> >::ConstSubmat {aka const Subview<const Matrix<float, 3ul, 3ul>, 2ul, 2ul>}' to 'const Densebase<Matrix<float, 3ul, 3ul> >&'

Upvotes: 0

Views: 232

Answers (1)

Carlton
Carlton

Reputation: 4297

I don't know what your compilation error(s) are, but overloads of Mathbase::coeff and Densebase::sub have the same signature (name and argument types), which will not compile. You can't overload a function just by it's return type, which it looks like you're trying to do.

Upvotes: 1

Related Questions