I have encountered an incomplete type error in designing my library's CRTP inheritance structure. I am cognizant of the fact that this might possibly be solved by way of type traits but I do not even know where to begin and would like some guidance in that regard.
Roughly speaking, Alg
and Geo
are two interfaces that inherit from a shared base. Alg
is fairly straightforward but Geo
is a bit more complex in that it takes as a template parameter a class deriving from Alg
. The incomplete type error is in reference to this functionality. Minimal reproducible example
The following skeleton illustrates the problem at hand.
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 ...
}
};
Below is an example of one of A
's derived classes and a usage example.
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);
}
The error occurs because the compute
function cannot be found in Geo<SpathSVD<SomeAlgVariant>, SomeAlgVariant>
. How can I fix this?