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
上实现重载时,它在矩阵上运行良好,但在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::coeff
和Densebase::sub
的重载具有相同的签名(名称和参数类型(,不会编译。你不能仅仅根据函数的返回类型来重载它,这看起来像是你正在尝试做的
相关文章:
- 以代数表达式中的数字和单位作为自变量的文字
- 使用工程空间在软件包中导入的线性代数库EIGEN
- 特征库,简单的线性代数操作,具有稀疏的矩阵,增加了其分配的尺寸
- C++ OpenMP 中线性代数函数的高效并行化
- C++ 多个图像上的 OpenCV 线性代数?
- 带有 TooN 和 ROS 的线性代数
- 线性代数的过载操作员
- 线性代数转换矩阵 - 通过乘以矩阵从点到不同点
- 使用犰狳线性代数包存储矩阵需要多少内存
- 如何设计:矩阵的线性代数例程
- 具有复数的任意精度线性代数c/c++库
- 建议为C++选择一个线性代数库
- 按递增顺序枚举代数表达式
- C++ eigen3 线性代数库,奇数性能结果
- 转换gsl线性代数以用于scalapack或其他并行矩阵库
- 线性代数的CPU指令集
- 结合线性代数库与Boost::Units
- 本征在其线性代数Ax=b中能否使用双精度以上?
- 特征线性代数求解器似乎很慢
- CRTP和表达式模板线性代数