C++ covariant return type error with multiple inheritance
c++, c++98, covariant, multiple-inheritance
Solution
TL;DR
Overriding `foo` in class `D`. `foo` methods can not covariant due to unrelated `X` and `Y` return types. Neither, can not overload due to different return types but same signature.
Explanation
Let's clean up the code to a smaller snippet with same issue:
class X {};
class Y {};
template<typename T>
class C {
public:
virtual T * foo() = 0;
};
class A : public C<X> {
public:
// Your code:
// X * foo() {}; <---- This method is irrelevant to the problem
// virtual X * foo() {};
// ^^^^^^^^^^^^^^^^^^^^^
// This method declared via inheritance and template
// and implicitly exists in this class, (look at keyword `virtual`)
};
class D : public A, public C<Y> {
public:
/*virtual*/ Y * foo() {}; // `virtual` comes from C<X>
};
Well, class `D` inherits two `foo` methods from `A` and `C<Y>`. These two imported methods can co-exists because they come from different parents and they can be called by qualified calls, for example `D d; d.A::foo();`.
But in this situation, the problem comes into the picture, when you try to override `foo` in class `D`:
/*virtual*/ Y * foo() {};
In class `D`, there is a method with signature `X * foo()` inherited from `A` and you're overriding method `Y * foo()`. These can not covariant, because `Y` is not derived from `X`. On the other hand, this `foo` can not overload another one, Because return type is not part of function signature.
It's good to read the error message of clang:
error: return type of virtual function 'foo' is not covariant with the return type of the function it overrides ('Y *' is not derived from 'X *')
virtual Y * foo() {};
Solution
The best solution is to simplify your design and get rid of these complex inheritance, templated and same name methods!!
Problem
I have the code which is equivalent to this one: ``` class X {}; class Y {}; template< typename T> class C { public: virtual T * foo() = 0; }; class A : public C< X> { public: X * foo() {}; }; class B : public A {}; class D : public B, public C< Y> { public: Y * foo() {}; //this is the only one method I need here. Not A::foo! }; ``` I got this errors: ``` error: invalid covariant return type for 'virtual Y* D::foo()' Y * foo() {}; ^ ``` and: ``` error: overriding 'virtual X* A::foo()' X * foo() {}; ^ ``` http://ideone.com/PAgTdX I believe I could write something in class B or D to prevent A::foo from inheriting, but I don't know what. Maybe there is some feature to rename conflict names in C++? PS> I can't use C++11, only good old C++98.