Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is single virtual inheritance not enough to resolve the dreaded diamond problem?

struct B { int i; };
struct D1 : virtual B {};
struct D2 : B {};  // <-- not virtual
struct DD : D1, D2 {};

Having coded above, still the compiler demands D2 also to be virtual:

DD d;
d.i = 0; // error: request for member `i' is ambiguous

What I don't understand is, once you have prompted compiler that B is virtual with respect to DD (via D1) then why it still i is ambiguous ?

(If my memory serves correct, the older VC++ (in 2006), was capable enough to make out this just with single virtual inheritance)

like image 445
iammilind Avatar asked Dec 22 '22 11:12

iammilind


2 Answers

B is not virtual with respect to DD - it is virtual with respect to D1. At the time D2 is created, it contains a full copy of B. So now DD has two implementations of B: one as part of D2, and one at the end (pointed by D1). And having two copies of i, using it is indeed ambiguous.

Had D2 also used virtual inheritance, instead of containing a copy of B, it would have contained a pointer to the instance of B that D1 is also pointing at, and DD would have contained only one instance of B.

I'll try to illustrate the memory layouts, hope this comes out right...:

Your case, with one virtual inheritance and one non-virtual -

|    D1    |   D2 + B |    B    |
+--+-------+----------+---------+
 |   vptr to B           ^
 +-----------------------|

Having both D1 and D2 inherit virtually -

|   D1   |   D2   |   B   |
+--+-----+---+----+-------+
 |         |         ^
 +---------+---------|
like image 91
eran Avatar answered Jan 17 '23 14:01

eran


You must read Diamond problem . Under the Approaches heading, for CPP, your case is clearly mentioned, your observation matches the one explained there.

like image 21
Gurpreet Singh Avatar answered Jan 17 '23 12:01

Gurpreet Singh