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() {};
^
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.
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!!