While working on providing reflection information about the base classes of user-defined classes, I stumbled upon a problem with ambiguous path to a base class. However, I do not understand when exactly that problem appears. Here are two pieces of code that seem to possess the ambiguity. However, only the second piece does not compile. The question is: what is the difference between the two pieces?
The following code compiles:
template <class Base1_ = void, class Base2_ = void, class Base3_ = void,
class Base4_ = void>
struct ManagedNode;
// For classes that do not derive
template <> struct ManagedNode<void, void, void, void> {
using Base1 = void; using Base2 = void; using Base3 = void;
using Base4 = void;
};
// For classes that derive from two base classes
template <class Base1_, class Base2_>
struct ManagedNode<Base1_, Base2_, void, void> : public Base1_, public Base2_ {
using Base2 = Base2_; // Base1 isn't needed in the real design,
// but that doesn't compile (see below)
};
// Some user classes for testing the concept
struct A : public ManagedNode<> {};
struct B : public ManagedNode<> {};
struct C : public ManagedNode<A, B> {}; // No ambiguity, although C
// derives from ManagedNode<>
// through both A and B.
If we add the following (which is the real way I would like to do things, since it allows to avoid duplication of code), the code does not compile:
// For classes that derive from a single base class
template <class Base1_>
struct ManagedNode<Base1_, void, void, void> : public ManagedNode<>,
public Base1_ {
using Base1 = Base1_;
};
struct D: public ManagedNode<A> {}; // error: direct base
// ‘ManagedNode<void, void, void, void>’
// inaccessible in ‘ManagedNode<A>’
// due to ambiguity
EDIT: Please note that, in the two-parameter case, I derive both from A and from B, both of which derive from ManagedNode<>. So, why isn't there ambiguity in that case as well as in the one-parameter case?