簡體   English   中英

從枚舉中獲取所有值

[英]Getting all values from an enum

我有Class1風格的Class1 (參見代碼)。 枚舉和函數從枚舉中獲取所有值。 值( FOO_1FOO_2等)因類別而異,以及值的數量( sizeof(Foos) )。 我調用該函數一旦獲取的sizeof枚舉,保留存儲器以及與所述第二呼叫我想獲得的所有值以*pFoos216中的示例代碼)。 有沒有更好的方法然后使用包含其中所有值的數組( 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM