我的课程风格为Class1
(见代码)。枚举和函数从枚举中获取所有值。值(FOO_1
,FOO_2
等)因类与类以及值的数量(sizeof(Foos)
)而异。
我调用函数一次得到枚举的大小,保留内存,第二次调用我想得到*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
}
};
答案 0 :(得分:5)
免责声明:无耻的插件 - 我是作者。
C ++中可以使用反射枚举。我写了一个仅限标题的库,它捕获了一堆&#34;模式&#34;在编译时,并提供如下语法:
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]);
它在内部的作用是使用宏来生成您声明的值的数组,类似于您的问题,并使用一堆其他技巧来允许您自然地使用初始化程序。然后它在数组顶部提供迭代器和其他东西。
这是一个链接:https://github.com/aantron/better-enums
编辑 - 内部
这是一个内部功能的伪代码草图。我之所以给出一个&#34; sketch&#34;是因为在进行此操作时需要考虑一些问题。我会谈谈所有最重要的因素。
ENUM(Class1, int, FOO_1 = 2, FOO_X = 1, FOO_BAR = 6)
从概念上扩展到
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"};
这是通过使用可变参数宏和字符串化来完成的。处理字符串的方法不仅要处理\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; }
};
这使得即使存在初始值设定项,_values
数组也可以声明。
当然,这些数组需要加上前缀,以便您可以拥有多个这样的枚举。他们还需要和#34; extern inline&#34;函数的链接,以便它们在多个编译单元之间共享。
答案 1 :(得分:3)
在c ++获得反射之前,你不会从你的枚举中获得任何数据!只是你无法从枚举中获得“所有”值。枚举只是一种命名空间,可以定义一些常量并可以自动枚举。根本不是。您没有文本表示,没有计数信息,没有文本信息的价值!
答案 2 :(得分:1)
是否有更好的方法使用包含其中所有值的数组
(size_t arr[3] ={FOO_1 , FOO_X, FOO_BAR })?
如果您将问题标记为C ++,我建议您放弃使用C语言做事,那么在C ++中更好的方法是使用std::vector
:
class Class1{
enum Foos{
FOO_1 = 2,
FOO_X = 1,
FOO_BAR = 6
};
public:
std::vector<int> GetFoos()
{
// return all enum values
return {FOO_1, FOO_X, FOO_BAR};
}
};
你可以这样使用它:
Class1 c1;
auto foos = c1.GetFoos();
std::cout << "I have " << c1.size() << " foos:\n";
for (const auto &foo : foos) std::cout << foo << '\n';
如果您不想在运行时创建向量,可以在声明为静态后创建向量:
class Alpha{
enum Alphas{
BETA = 0b101010,
GAMMA = 0x20,
EPSILON = 050
};
static const std::vector<int> m_alphas;
public:
const std::vector<int> &GetAlphas()
{
return m_alphas;
}
};
// https://isocpp.org/wiki/faq/ctors#explicit-define-static-data-mems
const std::vector<int> Alpha::m_alphas = {BETA, GAMMA, EPSILON};
我知道维护是一种负担,但由于无法迭代枚举的值,所有尝试迭代它们的代码也是一种负担。
也许在以下答案中,您可以找到一些有用的东西,以更好的方式迭代枚举: