Search code examples
c++gccdiamond-problem

Why does GCC give me an error: no unique final overrider?


In the code below, I get the following warning and error:

test.cpp:15: warning: direct base 'B' inaccessible in 'D' due to ambiguity
test.cpp:15: error: no unique final overrider for 'virtual void A::f()' in 'D'

But if I remove the virtual inheritance of B from A (i.e. struct B : public A), I only get the warning, no error.

struct A
{
  virtual void f() = 0;
};

struct B : public virtual A
{
  void f() {}
};

class C : public B
{};

struct D : public C, virtual B
{};

int main()
{
  return 0;
}

Why? Is this the dreaded diamond?


Solution

  • It's because C inherits in a non-virtual way from B while D inherits in a virtual way from B. This gives you B two times including two f().

    Try virtual inheritance of B in C.

    Update: So why does it work when you remove the virtual inheritance in B from A? Because it changes the "final overrider". Without virtual in B from A and in C from B you have A two times: once in C (with the final override of f() in B) and once in the virtual B in D (with the final override of f() in B). If you add back the virtual inheritance in B to A, A will be present only once and there will be two final overrides competing to implement the pure f() from A, both in B, once from C and once from the virtual B.

    As a workaround you could add a using to D, that is using C::f; or using B::f.

    See C++ 10.3/2