I would like to override a virtual function in a template-derived class. However, I would like to use the derived class as return type. Here is the corresponding code:
class Abstract {
public:
virtual Abstract* allocate() const = 0;
};
template <typename Derived>
class Base : public Abstract {
public:
Derived* allocate() const override {
return new Derived;
}
};
class Concrete : public Base<Concrete> {
public:
};
int main() {
Concrete c;
delete c.allocate();
}
Unfortunately, my compiler does not recognize that Derived is actually derived from Abstract and fails with the following error message.
mwe.cpp: In instantiation of ‘class Base<Concrete>’:
mwe.cpp:12:25: required from here
mwe.cpp:8:14: error: invalid covariant return type for ‘Derived* Base<Derived>::allocate() const [with Derived = Concrete]’
Derived* allocate() const override {
^~~~~~~~
mwe.cpp:3:23: note: overridden function is ‘virtual Abstract* Abstract::allocate() const’
virtual Abstract* allocate() const = 0;
^~~~~~~~
Moving the allocate function into the Concrete class would solve the issue, but leads to code duplication, when creating multiple concrete classes. Is there a way to make the compiler aware that Derived is actually derived from Abstract?