Even if B indeed derived from Clonable<B> , the problem here is that the Clonable<B> construct is invalid because it defines
B* clone() const override
which, of course, is not an override of AbstractClonable::clone() , since the compiler does not see B at this point as a child of AbstractClonable . Therefore, I believe that the problem is that the compiler cannot build the Clonable<B> B base.
The workaround (but not quite the same as you want) is to define
Clonable* clone() const override
in Clonable . As you mentioned in the comment, you can also define a free function
template<typename T> T* clone(const T* object) { return static_cast<T*>(object->clone()); }
Related: It turned out curiously repeating patterns and covariance
source share