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.

Original source

Related problems