使用CRTP创建特征矩阵

问题描述 投票:0回答:2

我有一个包含一些本征矩阵作为成员的类层次结构,但它们的大小依赖于派生类。我希望能够在基类中声明的矩阵但都被从派生类使用的大小。我以为我可以使用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;
}

但是,这是行不通的。有没有办法实现这样的事情?

编辑:

上面做的主要原因是,我有做一些矩阵代数,无论大小,其将工作职能。所以我想能够调用不同的派生类对象的功能,只是能够使用的,而不是每个矩阵大小不同的功能相同的功能。

还以具有类型基地的任何对象将具有矩阵垫它是从创建其大小将取决于派生类基础的接口。

c++ templates eigen crtp
2个回答
2
投票

正如我在我的评论说,实在没有理由使用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;
}

2
投票

直到它完全定义,你不能访问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本身是类模板,性状是(部分地)模板为好。无论这是有道理的,你的情况是很难从你提供的代码来告诉。

BTW:应该没有必要使Base::print() virtual。静态多态性的主要点是为了避免动态的多态性。

© www.soinside.com 2019 - 2024. All rights reserved.