0

我在设计库的 CRTP 继承结构时遇到了不完整的类型错误。我知道这可能通过类型特征来解决,但我什至不知道从哪里开始,并希望在这方面得到一些指导。

粗略地说,AlgGeo是从共享基础继承的两个接口。Alg相当简单,但Geo有点复杂,因为它将派生自 的类作为模板参数Alg。不完整的类型错误与此功能有关。最小的可重现示例

下面的框架说明了手头的问题。

template <typename Derived>
struct FitCRTP {
    Derived& derived() { return static_cast<Derived&>(*this); }
    Derived const& derived() const { return static_cast<Derived const&>(*this); }
};

template <typename Derived>
class FitBase : public FitCRTP<Derived> {
    friend class FitCRTP<Derived>;
    
    protected:
        FitBase() {}
        explicit FitBase(const Matrix& data) {
            this->derived().fit(data);
        }
};

template <typename Derived> 
class Alg : public FitBase<Derived> {
    friend class FitBase<Derived>;

    public:
        void fit (const Matrix& data) { 
            this->derived().compute(data);
        }

    protected:
        // constructors and misc functions ...
    }
};

template <typename Derived, class A,
    class = std::enable_if_t<std::is_base_of_v<Alg<A>, A>>> 
    class Geo : public FitBase<Geo<Derived, A>> {
        friend class FitBase<Geo<Derived, A>>;

        public:
            void fit (const Matrix& data) {        
                this->derived().compute(data, A(data).getGuess());    // <-- Problem line!
            }

        protected:
            // constructors and misc functions ...
        }
    };

下面是一个A派生类的示例和一个使用示例。

template <class A>
class SpathSVD : public Geo<SpathSVD<A>, A> {
    friend class Geo<SpathSVD<A>, A>;
    typedef Geo<SpathSVD<A>, A> Base;
public:
    SpathSVD<A> : Base() {}
    SpathSVD<A> (const Matrix& data) : Base(data) {}

protected:
    SpathSVD& compute (const Matrix& data, Guess g) {
        // Algorithm implementation ...
    }
}

int main() {
    SpathSVD<SomeAlgVariant> S;
    S.fit(data);
}

发生错误是因为在compute中找不到该函数Geo<SpathSVD<SomeAlgVariant>, SomeAlgVariant>。我怎样才能解决这个问题?

4

0 回答 0