如何使用宏在类中放置 typedef?

问题描述 投票:0回答:1

我有一个注册组件(类/类型)的组件注册表。我已经成功地做到了,如果您尝试将它与未注册的类一起使用,系统将无法工作。然而,即使它在一种类型的注册表中注册过一次,它也适用于所有类型的注册表,因为有一个:

template <typename T> static inline component_id;

这是通过宏放置在类内部的。

template <typename name>
struct ComponentRegistry
{
    using this_type = ComponentRegistry;

    template <typename component_t>
    static char register_new_component(const char* name)
    {
        static int counter = 0;
        component_t::template component_id<this_type> = counter++;
        /* REGISTER THE COMPONENT HERE*/
        
        return char(); /* ANYTHING. THE ONLY ONLY REASON THE DUMMY EXISTS IS TO TRIGGER THIS FUNCTION CALL ON PROGRAM INITIALIZATION */
    }
    template <typename component_t>
    int getComponentID()
    {
        /* IF THE COMPONENT WASN'T REGISTERED WITH ANY REGISTRY AT ALL, THEN THE template component_id DOESN'T EXIST AND SO IT WORKS
        - THE PROBLEM IS THAT EVEN IF IT WAS REGISTERED WITH ANOTHER REGISTRY THIS WILL STILL INSTANTIATE THE TEMPLATE
        - HOW DO I THROW A COMPILE ERROR? */
        return component_t::template component_id<this_type>; 
    }
};



#define REGISTER_COMPONENT_WITH_REGISTRY(comp_name, ecs_registry_type, comp_type) \
static inline char dummy_assignee_##ecs_registry_type = ecs_registry_type::register_new_component<comp_type>(comp_name); \
template <typename T> \
static inline int component_id;



struct ComponentRegistryName {}; // JUST USED TO DISTINGUISH. EACH TYPE CAN HAVE ITS OWN SET OF COMPONENTS

using ComponentRegistryType = ComponentRegistry<ComponentRegistryName>;

struct MyComponentType
{
    REGISTER_COMPONENT_WITH_REGISTRY("MyComponentTypeName", ComponentRegistryType, MyComponentType)

};

struct MyComponentType2
{
    /* NOT REGISTERED */
};

int main()
{
    ComponentRegistryType component_registry;

    component_registry.getComponentID<MyComponentType>(); // THIS SUCCEEDS BECAUSE IT WAS REGISTERED
    //component_registry.getComponentID<MyComponentType2>(); // THIS FAILS TO COMPILE BECAUSE THE COMPONENT WASN'T REGISTERED

}

这可以很好地检查组件是否已注册,因为如果没有注册:

但问题是,如果我想将组件注册到另一种注册表类型,则不再有限制检查,因为当我这样做时:

组件_t::模板组件_id

根本不存在。然而,即使使用注册到任何注册表的组件的模板参数调用 getComponentID,它也会成功。我希望使用宏在类中放置一个 typedef,我可以作为成员进行检查,如果它存在,那就很好。

c++ templates
1个回答
0
投票

也许是这样的:

// Declared but not defined.
template <typename Reg, typename Comp>
struct ComponentIdHolder;

注册宏会打印出类似这样的内容:

template<>
struct ComponentIdHolder<ecs_registry_type, comp_type> {
  static inline int component_id;
};

宏将被放置在组件类的外部,而不是像现在这样放置在组件类的内部。

在注册表中,您可以通过

ComponentIdHolder<this_type, component_t>::component_id
访问组件 ID。对于未提供专门化的任何类型对,这将无法编译。

© www.soinside.com 2019 - 2024. All rights reserved.