从枚举中获取所有值

tzi*_*ppy 5 c++ enums

我有类的风格Class1(见代码).枚举和函数从枚举中获取所有值.值(FOO_1,FOO_2等)从类到类别以及值(数量不同sizeof(Foos)).我调用该函数一次拿到的sizeof枚举,备用内存和与第二呼叫我想所有的值*pFoos(2,1,6在示例代码中).有没有更好的方法然后使用包含所有值的数组(size_t arr[3] ={FOO_1 , FOO_X, FOO_BAR })?

class Class1{
    enum Foos{
        FOO_1 = 2,
        FOO_X = 1,
        FOO_BAR = 6
    }
};

Class1::GetFoos(size_t* pFoos, size_t* pSize)
{
    size_t len = sizeof(Foos);
    if (len > *pSize)
    {   //Call function once to get the size
        *pSize= len ;
        return -1;
    }
    for(size_t i = 0; i< *pSize; i++)
    {
       //copy all enum values to pFoos
    }
};
Run Code Online (Sandbox Code Playgroud)

ant*_*ron 5

免责声明:无耻插件 - 我是作者.

C++中可以使用反射枚举.我编写了一个仅限头文件库,它在编译时捕获了一堆"模式",并为您提供如下语法:

ENUM(Class1, int, FOO_1 = 2, FOO_X = 1, FOO_BAR = 6)

size_t count = Class1::_size;

for (size_t index = 0; index < Class1::_size; ++index)
    do_anything(Class1::_values()[index]);
Run Code Online (Sandbox Code Playgroud)

它在内部的作用是使用宏来生成您声明的值的数组,类似于您的问题,并使用一堆其他技巧来允许您自然地使用初始化程序.然后它在数组顶部提供迭代器和其他东西.

这是一个链接:https://github.com/aantron/better-enums

编辑 - 内部

这是一个内部功能的伪代码草图.我只给出一个"草图"的原因是因为在进行此操作时需要考虑许多问题.我会触及所有最重要的元素.

ENUM(Class1, int, FOO_1 = 2, FOO_X = 1, FOO_BAR = 6)
Run Code Online (Sandbox Code Playgroud)

从概念上扩展到

struct Class1 {
    enum _enumerated { FOO_1 = 2, FOO_X = 1, FOO_BAR = 6 };

    // Fairly obvious methods for how to iterate over _values and
    // _names go here. Iterators are simply pointers into _values
    // and _names below.

    static size_t _size = sizeof(_values) / sizeof(int);

    int _value;
};

int _values[] = {(fix_t<Class1>)Class1::FOO_1 = 2,
                 (fix_t<Class1>)Class1::FOO_X = 1,
                 (fix_t<Class1>)Class1::FOO_BAR = 6};
const char *_names[] = {"FOO_1 = 2", "FOO_X = 1", "FOO_BAR = 6"};
Run Code Online (Sandbox Code Playgroud)

这是通过使用可变参数宏和字符串化来完成的.处理字符串的方法不仅要处理\0空格,还要处理空格和等于终结符,它们允许它们忽略你看到的字符串化常量中的初始值设定项_names.

该类型fix_t是必要的,因为在数组初始值设定项内的赋值不是有效的C++.该类型的作用是获取枚举的值,然后通过重载的赋值运算符忽略赋值,然后返回原始值.草图:

template <typename Enum>
struct fix_t {
    Enum _value;

    fix_t(Enum value) : _value(value) { }
    const fix_t& operator =(int anything) const { return *this; }
    operator Enum() const { return _value; }
};
Run Code Online (Sandbox Code Playgroud)

这使得_values即使在存在初始化器的情况下也可以声明阵列.

当然,这些数组需要加上前缀,以便您可以拥有多个这样的枚举.它们还需要与函数的"extern inline"链接相同,以便它们在多个编译单元之间共享.


Kla*_*aus 4

在 C++ 获得反射之前,您将无法从枚举中获得任何数据!简单地说,您无法从枚举中获取“所有”值。枚举只是一种命名空间,可以在其中定义一些常量并可以自动枚举。根本就没有更多。你没有文本表示,没有计数信息,对文本信息没有价值!