I’ve been dealing with a frustrating problem recently. I have a lot of reflection code I’d like to hide in macros. These COMPONENT_x() macros are used to like so:
class ComponentBase : public IComponent
{
COMPONENT(ComponentBase)
};
class ComponentDerived1 : public ComponentBase
{
COMPONENT_DERIVED(ComponentDerived1, ComponentBase)
};
The above is completely valid. However, I would like a compile error to occur in this case:
class ComponentDerived2 : public ComponentDerived1
{
COMPONENT_DERIVED(ComponentDerived2, ComponentBase)
// ^^^^^^^^^^^^^
// This type claims to have a superclass of ComponentBase in the above macro,
// but we really derive from ComponentDerived1.
//
// I want this to result in a compile error.
};
That is, when I’m claiming that my super class (or my base class) is ComponentBase when my the super class is actually ComponentDerived1, I would ideally like a compile-time error.
The reason I cannot easily detect this case is that while my super class is ComponentDerived1, that class’ super is ComponentBase — and thus it is also one of my base classes. (I understand that ComponentDerived1 is-a ComponentBase, so maybe there is a better phrase to use than “base class.”)
There were some comments questioning why I want to do this. I’m using an optimized system of component generation which puts all objects of the same type into discrete buffers, so generating knowledge of class relationships is important if I want to have an API such as getComponentsThatImplement(ComponentDerived1::getType());.
I had hacked together one solution that works with g++:
class ComponentBase : public IComponent
{
COMPONENT(ComponentBase)
protected:
static void helperComponentBase(); // COMPONENT(ComponentBase)
};
class ComponentDerived1 : public ComponentBase
{
COMPONENT_DERIVED(ComponentDerived1, ComponentBase)
private:
using ComponentBase::helperComponentBase; // COMPONENT_DERIVED(..., ComponentBase)
};
class ComponentDerived2 : public ComponentDerived1
{
COMPONENT_DERIVED(ComponentDerived2, ComponentBase)
private:
using ComponentBase::helperComponentBase; // error: this function is already hidden
}
Unfortunately, clang with Xcode 4.3.2 seems to not support using in this way. I’ve check boost’s type traits library and don’t see anything useful. I am using C++11, so I can use modern constructs.
Any other clever ideas?
You can exploit the fact that from a c’tor you cannot directly call your super’s super’s c’tor: