代码之家  ›  专栏  ›  技术社区  ›  greywolf82

扩展本征引用类

  •  3
  • greywolf82  · 技术社区  · 6 年前

    我想把 Ref Eigen 类以使用自定义类。我有以下代码:

    #include <iostream>
    #include <eigen3/Eigen/Dense>
    
    class Interface {
    public:
        virtual ~Interface() {
        }
        virtual void customMethod() const = 0;
    };
    
    class MyVectorType: public Eigen::Matrix<double, 3, 1, Eigen::DontAlign>,
            public Interface {
    public:
        MyVectorType(void) :
                Eigen::Matrix<double, 3, 1, Eigen::DontAlign>() {
        }
        typedef Eigen::Matrix<double, 3, 1, Eigen::DontAlign> Base;
        // This constructor allows you to construct MyVectorType from Eigen expressions
        template<typename OtherDerived>
        MyVectorType(const Eigen::MatrixBase<OtherDerived>& other) :
                Eigen::Matrix<double, 3, 1, Eigen::DontAlign>(other) {
        }
        // This method allows you to assign Eigen expressions to MyVectorType
        template<typename OtherDerived>
        MyVectorType & operator=(const Eigen::MatrixBase<OtherDerived>& other) {
            this->Base::operator=(other);
            return *this;
        }
        virtual void customMethod() const {
            std::cout << rows() << std::endl;
        }
    };
    
    template<typename T, int Options>
    class MyRef: public Eigen::Ref<typename T::Base, Options, Eigen::Stride<0, 0> >,
            public Interface {
    public:
        typedef Eigen::Ref<typename T::Base, Options, Eigen::Stride<0, 0> > Base;
        template<typename Derived>
        MyRef(Eigen::DenseBase<Derived>& expr) :
                Eigen::Ref<typename T::Base, Options, Eigen::Stride<0, 0> >(expr) {
        }
        virtual void customMethod() const {
            std::cout << rows() << std::endl; // <-----error
        }
        EIGEN_INHERIT_ASSIGNMENT_OPERATORS(MyRef)};
    
    template<typename T, int Options>
    class MyRef<const T, Options> : public Eigen::Ref<typename T::Base, Options,
            Eigen::Stride<0, 0> >, public Interface {
    public:
        template<typename Derived>
        MyRef(const Eigen::DenseBase<Derived>& expr) :
                Eigen::Ref<typename T::Base, Options, Eigen::Stride<0, 0> >(expr) {
        }
        virtual void customMethod() const {
            std::cout << rows() << std::endl; // <-----error
        }
    };
    
    void init(MyRef<MyVectorType, Eigen::Unaligned> m) {
        m.customMethod();
    }
    
    int main() {
        Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::AutoAlign, 12,
                12> mm(3, 1);
        Eigen::Map<MyVectorType::Base> map(mm.data(), 3, 1);
        MyRef<MyVectorType, Eigen::Unaligned> ref(map);
        init(ref);
        std::cout << mm << std::endl;
        return 0;
    }
    

    以便调用自定义方法,如方法 init() ,之间必须使用相同的接口 MyVectorType MyRef . 所以我想用 Interface 班级。

    问题是:这个代码不能编译,因为我不能调用 rows() 里面 米雷夫 ,所以我不知道如何访问 肌电型 或中的基础数据 Ref 类来调用其他方法。

    我尝试过 derived() 但不起作用。我看了源代码,但我不明白 裁判 可正常使用所有接口 DenseBase . 我想为我的自定义方法做同样的事情。

    GCC错误:

    ../main.cpp:49:16: error: there are no arguments to ‘rows’ that depend on a template parameter, so a declaration of ‘rows’ must be available [-fpermissive]
       std::cout << rows() << std::endl;
                    ^~~~
    ../main.cpp:49:16: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
    ../main.cpp: In member function ‘virtual void MyRef<const T, Options>::customMethod() const’:
    ../main.cpp:63:16: error: there are no arguments to ‘rows’ that depend on a template parameter, so a declaration of ‘rows’ must be available [-fpermissive]
       std::cout << rows() << std::endl;
                    ^~~~
    
    1 回复  |  直到 6 年前
        1
  •  3
  •   JeJo    6 年前

    当A Base 类依赖于模板参数,即使 Derived (让我们说) member_base 继承自 基地 简单地使用 成员库 在里面 衍生的 类,不等于 this->member_base .

    那就是

    template<typename T>
    class Base { public:    void member_base(); };
    
    template<typename T>
    class Derived : Base<T> 
    {
    public:
        void member_derived() 
        {
            member_base(); // calls external(global) member_base() or error
        }
    };
    

    在你的情况下,发生了什么 rows() 与上述情况完全相同。

    您需要使用 this-> Base<T>:: ,对于您继承的所有成员 基地 .

    以你为例

    this->row() 
    

    Eigen::Ref<typename T::Base, Options, Eigen::Stride<0, 0> >::rows()