繁体   English   中英

使用CRTP创建特征矩阵

[英]Using CRTP to create Eigen matrix

我有一个类层次结构,其中包含一些本征矩阵作为成员,但它们的大小取决于派生类。 我希望能够在基类中声明矩阵,但具有从派生类中使用的大小。 我以为可以为此使用CRTP,但不确定我是否正确使用它。 这是我尝试的代码

template<typename T>
class Base {
public:
    const int matSize = static_cast(T*)(this)->_matSize;
    Eigen::Matrix<int, matSize, mastSize> Mat = Eigen::Matrix<int, matSize, matSize>::Zero();

    virtual void print() { std::cout << Mat << std::endl; };
};

class Derived1 : public Base<Derived1>{
public:
    const int _matSize = 3;
};

class Derived2 : public Base<Derived2>{
public:
    const int _matSize = 4;
};

int main(){
    Derived1 d1;
    d1.print();   // print a 3x3 zero matrix

    Derived2 d2;
    d2.print();   // print a 4x4 zero matrix

    std::cin.get();
    return 0;
}

但是,这不起作用。 有没有办法实现这样的目标?

编辑:

进行上述操作的主要原因是,我具有执行某些矩阵代数的函数,这些函数无论大小都可以工作。 因此,我希望能够在不同派生类的对象上调用该函数,并且仅能够使用相同的函数,而不是针对每个矩阵大小使用单独的函数。

还有一个接口,Base类型的任何对象都将具有矩阵Mat,矩阵Mat的大小取决于从其创建Base的派生类。

正如我在评论中说的那样,确实没有理由仅将CRTP用于您所指示的内容,但是如果出于其他原因而在此模式下进行设置,则应执行以下操作(我没有Eigen::Matrix因此,我为编译器添加了必要的接口):

#include <iostream>

namespace Eigen {
    template<typename T, int W, int H>
    class Matrix {
    public:
        static Matrix<T,W,H> Zero() {
            return Matrix<T, W, H>{};
        }

        std::ostream &print_on(std::ostream &strm) const {
            return strm;
        }
    };
}

template <typename T, int W, int H>
std::ostream &operator<<(std::ostream &strm, Eigen::Matrix<T,W,H> const &matrix) {
    return matrix.print_on(strm);
}

template<typename T, int S>
class Base {
public:
    Eigen::Matrix<int, S, S> Mat = Eigen::Matrix<int, S, S>::Zero();

    virtual void print() { std::cout << Mat << std::endl; };
};

class Derived1 : public Base<Derived1,3>{
public:
};

class Derived2 : public Base<Derived2,4>{
public:
};

template <int Size>
class AdvertisingDerived : public Base<AdvertisingDerived<Size>,Size> {
public:
    constexpr static int matrixSize = Size;
};

int main(){
    Derived1 d1;
    d1.print();   // print a 3x3 zero matrix

    Derived2 d2;
    d2.print();   // print a 4x4 zero matrix

    AdvertisingDerived<3> ad1;

    AdvertisingDerived<4> ad2;

    std::cin.get();
    return 0;
}

在完全定义Derived1之前,您不能访问Derived1成员(从Derived1之外的任何地方)。 解决此问题的通常方法是使用某种特征类:

template<class D>
struct MyTraits;

template<typename T>
class Base {
public:
    static const int matSize = MyTraits<T>::_matSize;
    Eigen::Matrix<int, matSize, matSize> Mat = Eigen::Matrix<int, matSize, matSize>::Zero();

    virtual void print() { std::cout << Mat << std::endl; };
};

class Derived1;
template<>
struct MyTraits<Derived1> {static const int _matSize = 3;};

class Derived1 : public Base<Derived1>{
public:
};

Godbolt: https ://godbolt.org/z/pf-B_R

特别是,如果Derived1本身是一个类模板,那么特征也将被(部分)模板化。 从您提供的代码中很难判断这是否有意义。

顺便说一句:应该没有必要将Base::print() virtual 静态多态的要点是避免动态多态。

暂无
暂无

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

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