Я недавно столкнулся с неприятной проблемой. У меня есть много кода отражения, который я хотел бы скрыть в макросах. Эти макросы COMPONENT_x()
используются так:
class ComponentBase : public IComponent
{
COMPONENT(ComponentBase)
};
class ComponentDerived1 : public ComponentBase
{
COMPONENT_DERIVED(ComponentDerived1, ComponentBase)
};
Вышеуказанное является полностью действительным. Тем не менее, я хотел бы, чтобы в этом случае произошла ошибка компиляции:
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.
};
То есть, когда я утверждаю, что мой суперкласс (или мой базовый класс) равен ComponentBase
, когда мой суперкласс на самом деле ComponentDerived1
, я бы идеально хотел ошибку во время компиляции.
Причина, по которой я не могу легко обнаружить этот случай, состоит в том, что, хотя мой суперкласс ComponentDerived1
, этот класс 'super' ComponentBase
- и, следовательно, это также один из моих базовых классов. (Я понимаю, что ComponentDerived1
is-a ComponentBase
, поэтому, возможно, есть более подходящая фраза, чем «базовый класс».)
Были некоторые комментарии, спрашивающие, почему я хочу это сделать. Я использую оптимизированную систему генерации компонентов, которая помещает все объекты одного и того же типа в отдельные буферы, поэтому важно знать знания о связях классов, если я хочу иметь такой API, как getComponentsThatImplement(ComponentDerived1::getType());
.
Я взломал вместе одно решение , которое работает с 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
}
К сожалению, clang с Xcode 4.3.2, похоже, не поддерживает using
таким образом. Я проверил библиотеку признаков типа boost и не вижу ничего полезного. Я использую C ++ 11, поэтому я могу использовать современные конструкции.
Какие-нибудь другие умные идеи?