我有类的风格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)
免责声明:无耻插件 - 我是作者.
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"链接相同,以便它们在多个编译单元之间共享.
在 C++ 获得反射之前,您将无法从枚举中获得任何数据!简单地说,您无法从枚举中获取“所有”值。枚举只是一种命名空间,可以在其中定义一些常量并可以自动枚举。根本就没有更多。你没有文本表示,没有计数信息,对文本信息没有价值!
| 归档时间: |
|
| 查看次数: |
3442 次 |
| 最近记录: |