我在设计库的 CRTP 继承结构时遇到了不完整的类型错误。我知道这可能通过类型特征来解决,但我什至不知道从哪里开始,并希望在这方面得到一些指导。
粗略地说,Alg
和Geo
是从共享基础继承的两个接口。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>
。我怎样才能解决这个问题?