-1

Below is the class hierarchy I have.

All Ixxxx classes are interfaces (abstract classes with no member data).

All arrows represent inheritance.

Colors are only here to provide better visualisation.

class hierarchy

Somewhere in the code using these classes, I have to pass a Track* where an IConnectableTrack* is expected, and I get the following compilation error:

error: ‘IConnectableTrack’ is an ambiguous base of ‘Track’

I know this is a matter of multiple inheritance, but I tried multiple combinations of virtual inheritances to no avail.

In particular, I thought virtualizing both inheritances between red interfaces and both inheritances between green classes (i.e. all purple arrows) would be enough, but it does not solve the problem.

What would be the correct construct here?

Edit: this question is different from the mentionned one since it includes pure abstract classes, which relates to the specific error message referenced.

Silverspur
  • 891
  • 1
  • 12
  • 33
  • 3
    Possible duplicate of [How does virtual inheritance solve the "diamond" (multiple inheritance) ambiguity?](https://stackoverflow.com/questions/2659116/how-does-virtual-inheritance-solve-the-diamond-multiple-inheritance-ambiguit) – Charles Oct 02 '17 at 22:43
  • 1
    ConnectableTrack should be "virtual IConnectableTrack" already. – tevemadar Oct 02 '17 at 22:46
  • @Charles the question you mention only deals with member data. Here the issue arise with pure abstract classes. – Silverspur Oct 02 '17 at 22:48
  • 2
    @Silverspur I'm aware; however, there's still diamond inheritance of `ConnectableTrack` so I suggested it. – Charles Oct 02 '17 at 22:49

1 Answers1

4

Your Track has four instances of IConnectableTrack and compiler doesn't know which one to use. Make top 3 arrows virtual.

https://wandbox.org/permlink/Y1e9LwDI0IVaERaW

class IConnectableTrack {};
class Object {};
class ConnectableTrack: public virtual IConnectableTrack, public Object {};
class IOccupiableTrack: public virtual IConnectableTrack {};
class OccupiableTrack: public IOccupiableTrack {};
class ISignalledTrack: public virtual IConnectableTrack {};
class SignalledTrack: public ISignalledTrack {};
class Track: public OccupiableTrack, public SignalledTrack {};

void f(IConnectableTrack&) {}

int main() {
    Track t;
    f(t);
}
Andriy Tylychko
  • 15,967
  • 6
  • 64
  • 112