I am going through Chapter 3 of Alexandrescu's Modern C++ Design. It explains the implementation of HierarchyGenerators.h, however changes have been made to the library since then.
I am unable to understand how the ScatterHierarchyTag
solves the ambiguity in resolving Field
function (the function allows us to access members defined by particular Base<type>
, for example Field<int>(Object)
would get us a &Base<int>
to Object
), when the typelist used to generate hierarchy has duplicates. (ex: GenScatterHierarchy<TYPELIST_4(int,int,string,Widget), Base> Object
) I see that it adds a unique "type/tag" in each of the branches, right before the root Base<type>
class, but still ambiguity is there right?
Thank you in advance.
EDIT:
Chart showing multiple inheritance issue with repeated types in typelist. GSH = GenScatterdHierarchy
I believe the unique tags are inserted seperately, for each of the two connections to Base<int>
(marked one by blue line) (same goes for other base classes at root)
Also, I inserted picture to make it easier for everyone to understand. Let me know if it does not fit in stackoverflow's guidelines and I shall remove it.
ScatterHierarchyTag
is not removing ambiguity. What it does, is making an ambiguous base class accessible.
Consider the following class hierarchy:
class A {};
class B : public A {};
class C : public A, public B {};
Class C
contains two copies of class A
(it makes more sense when A is not empty :), one is created because of direct inheritance, another — because of indirect inheritance through B
. You can access the second instance converting to B
first:
A &indirect_base = static_cast<B>(C_instance);
For the other instance, there is simply no way of accessing it. Because of that, it is called "inaccessible base".
This example embeds naturally in class hierarchy created by GenScatterHierarchy
:
GenScatterHierarchy<int, Base>
is A
,GenScatterHierarchy<TYPELIST_3(int,string,Widget)>
is B
,GenScatterHierarchy(TYPELIST_4(int,int,string,Widget))
is C
.So, instance of Base<int>
created for the first int
in type list is an inaccessible base. However, if ScatterHierarchyTag
is added, we can access it by casting to GenScatterHierarchy<ScatterHierarchyTag<int, TYPELIST_3(int,string,Widget)>, Base>
first.