gpt4 book ai didi

c++ - CRTP 和表达式模板 线性代数

转载 作者:行者123 更新时间:2023-11-28 06:15:40 26 4
gpt4 key购买 nike

我正在尝试修改我的线性代数模块以避免虚拟 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); }
};

请注意,它声明了两种对父矩阵(共矩阵)进行引用的类型然后我有 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); 上崩溃甚至没有进入功能。

这是在 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 的重载具有相同的签名(名称和参数类型),将无法编译。您不能仅通过函数的返回类型来重载函数,这看起来就像您正在尝试做的那样。

关于c++ - CRTP 和表达式模板 线性代数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30385846/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com