具有多重继承的 C++ 协变返回类型错误

Val*_* T. 5 c++ multiple-inheritance covariant c++98

我有与此等效的代码:

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!
};
Run Code Online (Sandbox Code Playgroud)

我收到这个错误:

error:   invalid covariant return type for 'virtual Y* D::foo()'
 Y * foo() {};
     ^
Run Code Online (Sandbox Code Playgroud)

和:

error:   overriding 'virtual X* A::foo()'
 X * foo() {};
     ^
Run Code Online (Sandbox Code Playgroud)

http://ideone.com/PAgTdX

我相信我可以在B类或D类中编写一些内容来阻止A::foo继承,但我不知道是什么。也许 C++ 中有一些重命名冲突名称的功能?

PS> 我不能使用 C++11,只能使用旧的 C++98。

mas*_*oud 4

长话短说

foo在课堂上压倒一切Dfoo由于不相关XY返回类型,方法不能协变。两者都不能由于返回类型不同但签名相同而重载。


解释

让我们将代码清理为具有相同问题的较小片段:

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>
};
Run Code Online (Sandbox Code Playgroud)

那么,类从和D继承了两个foo方法。这两个导入的方法可以共存,因为它们来自不同的父方法,并且可以通过限定调用来调用它们,例如.AC<Y>D d; d.A::foo();

 

foo但在这种情况下,当您尝试在类中重写时,问题就出现了D

/*virtual*/ Y * foo() {};
Run Code Online (Sandbox Code Playgroud)

在类中D,有一个方法的签名X * foo()继承自A并且您正在重写方法Y * foo()。这些不能协变,因为Y不是源自X。另一方面,这foo不能重载另一个,因为返回类型不是函数签名的一部分

 

看看clang的错误信息就好了:

错误:虚拟函数“foo”的返回类型与它覆盖的函数的返回类型不协变(“Y *”不是从“X *”派生的)

virtual Y * foo() {};
Run Code Online (Sandbox Code Playgroud)

解决方案

最好的解决方案是简化你的设计并摆脱这些复杂的继承、模板化和同名方法!