gpt4 book ai didi

c++ - C++元编程:为每个枚举类型成员创建typedef作为类型

转载 作者:行者123 更新时间:2023-12-03 07:21:00 25 4
gpt4 key购买 nike

我想知道是否可以从元类生成用于元编程目的的类型集。
我最初是C#程序员,并且习惯于使用很多属性进行反射和元编程。例如,用C#编写类似的代码段是我的一般模式:

public enum ComponentEnum { Component1, Component2, Component3 }

[Component(ComponentEnum.Component1)]
public class Component1
{
/* Some code */
}

public static class ComponentsMeta
{
private static Dictionary<Type, ComponentEnum> map;
static ComponentMeta() { /*process the whole codebase via reflection, search Component marked classes an fill the map */}
public static bool IsComponent<T>() => map.ContainsKey(typeof(T));
public static int GetComponentUID<T>() => (int)map[typeof(T)];
}
当然,这是一个非常基本的片段,没有断言和其他内容,但是我相信您已经明白了。
我想在C++代码段中做出相同的行为。我要确切地做的是创建一个名为 Components的类型,该类型将包含一些实用程序功能,例如 bool Components::isComponent<T>()size_t Components::getComponentUID<T>()或一些相关的东西。到目前为止,我所看到的最好的方法是自己写下来,制作一个像
template <typename Ts..>
class ComponentsData
{
/* functions impl here */
}

typedef ComponentsData<C1, C2, C3> Components;
因此,现在我可以询问 Components<C1>::getComponentUID(),它返回我该组件的uid(取决于它作为模板参数的位置或该组件的constexpr值,这无关紧要)。但这是一种非常不方便的方法,我想知道是否可以将宏放在组件类中,还是可以使用属性和代码生成步骤或其他方法。换句话说,我的目标是以某种方式标记该组件集中应包含的类,并在以后使用它。为此,C++可以提供什么?
如果我可以像执行C#方式那样做就可以了-制作一个枚举类,列出其中的所有组件,并在组件类内写入constexpr值(或者在枚举类附近的某处,这两种方式都对我有好处) 。
我的意思是这样的:
    /* ComponentsEnum.h */
enum class ComponentsEnum { Comp1, Comp2, Comp3 };
// Here is some magic to generate Components<C1, C2, C3> metaclass.

/* another file */
#include "ComponentsEnum.h"
struct C1 { const ComponentsEnum MyValue = ComponentsEnum::Comp1; };
或类似的东西
    /* ComponentsEnum.h */
enum class ComponentsEnum { Comp1, Comp2, Comp3 };

// Here is all the magic
// All enum members concats into `Components<Comp1, Comp2, Comp3, ...>`
ConcatAll<ComponentsEnum>();

/* another file */
#include "ComponentsEnum.h"
struct Comp1 { };
或一些带有宏魔术的东西:
    /* ComponentsEnum.h */
enum class ComponentsEnum { Comp1, Comp2, Comp3 };
#define InitMeta(ComponentsEnumMember) /* Some Magic */

/* another file */
#include "ComponentsEnum.h"
struct Comp1 { InitMeta(ComponentsEnum::Comp1) };
提前致谢!

最佳答案

跟随我的评论。
您可以在C++ 17中执行以下操作:

// In register.hpp
int register_me();

// In register.cpp
int register_me(){
static int id = 0;
return id++;
}

// In wherever.hpp
// #include "register.hpp"
struct component{
inline static int id = register_me();
};


在C++ 17之前的版本中,需要将每个 .cpp的定义和初始化移至 component::id
但我强烈建议不要使用此功能。重新考虑您的设计,将类型转换为ID对我来说是一种代码味道。 C++并不是真正为执行此类操作而设计的,它以后可能会困扰您。
上面的代码依赖于程序启动时对所有静态变量的动态初始化。未指定顺序,每次编译可能会导致分配不同的ID。
绝对不要在100%确保知道工具链的编译,链接和加载过程如何工作之前将其放入任何共享库中,因为这些过程不在C++ Standard的范围内。

关于c++ - C++元编程:为每个枚举类型成员创建typedef作为类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65135165/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com