繁体   English   中英

CRTP和表达式模板线性代数

[英]CRTP and Expression template Linear algebra

我试图修改我的线性代数模块,以避免虚拟vtable的事情。尝试使用CRTP和表达式模板。 我采用了应该测试整个事情的基本方法,但我无法使其正常工作。

我有4个类别,例如:基础CRTP类别,此处为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); }
};

然后,在其中实现了转置,行列式等功能的Densebase:

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

请注意,它声明了两种在父矩阵(co-matrix)上进行引用的类型。然后我有了Matrix类,该类通过访问其存储来实现coeff函数:

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

现在,两件事不起作用:

  • 我实现了一个使用拉普拉斯展开的行列式帮助程序(计算共矩阵行列式并将其求和,可惜它无法编译

     template <typename Derived, std::size_t N> struct det_helper { static inline typename dense_traits<Derived>::T run(const Densebase<Derived>& dense) { typename dense_traits<Derived>::T det = 0; // Laplace expansion for (std::size_t i = 0; i < N; ++i) det += ((i & 1) ? -1 : 1)*dense.coeff(0,i)*det_helper::run(dense.sub(0,i)); return det; } }; template <typename Derived> struct det_helper<Derived, 2> { static inline typename dense_traits<Derived>::T run(const Densebase<Derived>& dense) { return dense.coeff(0,0)*dense.coeff(1,1) - dense.coeff(0,1)*dense.coeff(1,0); } }; 

并这样调用:

T determinant() const
{
  return det_helper<Derived, dense_traits<Derived>::M>::run(derived());
}
  • 第二个问题是当我在<< stream operator上实现重载时,该重载在Matrix上工作正常,但在stream << matrix.sub(0,0);上崩溃stream << matrix.sub(0,0); 甚至没有进入功能。

这是在PASTEBIN上上传的完整代码

并按要求输出错误:

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> >&'

我不知道您的编译错误是什么,但是Mathbase::coeffDensebase::sub重载具有相同的签名(名称和参数类型),无法编译。 您不能仅通过函数的返回类型来重载它,这看起来就像您正在尝试做的那样。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM