[英]Getting all values from an enum
我有Class1
風格的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
}
};
免責聲明:無恥插件 - 我是作者。
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]);
它在內部的作用是使用宏來生成您聲明的值的數組,類似於您的問題,並使用一堆其他技巧來允許您自然地使用初始化程序。 然后它在數組頂部提供迭代器和其他東西。
這是一個鏈接: https : //github.com/aantron/better-enums
編輯 - 內部
這是一個內部功能的偽代碼草圖。 我只給出一個“草圖”的原因是因為在進行此操作時需要考慮許多問題。 我會觸及所有最重要的元素。
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
看到的字符串化常量中的初始值_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
數組也可以聲明。
當然,這些數組需要加上前綴,以便您可以擁有多個這樣的枚舉。 它們還需要與函數的“extern inline”鏈接相同,以便它們在多個編譯單元之間共享。
在c ++獲得反射之前,你不會從你的枚舉中獲得任何數據! 只是你無法從枚舉中獲得“所有”值。 枚舉只是一種命名空間,可以定義一些常量並可以自動枚舉。 根本不是。 您沒有文字表示,沒有計數信息,沒有文本信息的價值!
有沒有更好的方法然后使用包含其中所有值的數組
(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};
我知道這是一個維護的負擔,但由於沒有辦法迭代枚舉的值,所有試圖迭代它們的代碼也是一個負擔。
也許在以下答案中,您可以找到一些有用的東西,以更好的方式為您的目標迭代枚舉:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.