确定枚举类中的枚举数(或任何枚举类中的特定枚举值)

时间:2017-10-21 20:31:13

标签: c++ templates generics enums

我已经相当确定在没有创建自己的enum implamentation的情况下我要问的是不可能的,但我认为值得把它放在那里以防万一。我错过了一些东西,因为它会简化我在工作和我自己的项目中经常遇到的情况。

基本上,我想要一种返回枚举类中所有枚举列表的通用方法,或者至少是返回所有正面枚举的通用方法,直到枚举特定但其他预定点为止。好吧,最后一个想法令人困惑,所以我会在下面发布我的意思的伪代码...

设置特定枚举键的方法?"用于返回给定键之前的正枚举数:

template<typename EnumType>
std::vector<EnumType> getFullEnumList()
{
    std::vector<EnumType> fullEnumList;

    for (enumIndex = 0; enumIndex < EnumType::NumEnums; enumIndex++)
        fullEnumList.push_back(static_cast<EnumType>(enumIndex));

    return fullEnumList;
}

我猜这不是一个实际的事情,如上所述,因为编译器并不关心我所谓的每个enum类值,只有它&#39; s值和类类型......编译器在最终编译阶段处理的所有内容对吧?

我认为我的第一个想法会涉及某种形式:

EnumClass::size()

...函数,我已经知道它不存在,但我目前对枚举类的细节知之甚少,无法理解为什么这样做不可能实现未来的c ++迭代......我猜测它不可能,或者在大多数enum类用例中它会是一个不受欢迎的额外开销,否则他们已经在几年前实现了它......

但是要缩小我的实际问题,除了额外的知识块之外,你们可以向我提供有关上述思考的内容,是否有一些通用的方法来做到这一点我还没有想过?

提前为您的见解干杯,

皮特

3 个答案:

答案 0 :(得分:2)

如果您使用带有顺序值的枚举,您可以使用这个旧技巧。

为您拥有的每个枚举定义Max(以及可选的Min)值:

enum class MyEnum
{
    Sunday,
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Max,
    Min = Sunday // (Optional, see following notes)
};

定义您的枚举方法如下:

template<typename EnumType>
std::vector<EnumType>
getFullEnumList(int from = (int)EnumType::Min, int to = (int)EnumType::Max)
{
    std::vector<EnumType> fullEnumList;

    for (auto enumIndex = from; enumIndex < to; enumIndex++)
        fullEnumList.push_back(static_cast<EnumType>(enumIndex));

    return fullEnumList;
}

使用EnumType::MinEnumType::Max作为默认值可以防止对未正确定义的枚举类型调用此方法。

注意:如果您的所有枚举仅使用值,则可以避免Min的删除并使用int from = 0 {{1} }}

并且使用这种方法:

getFullEnumList

答案 1 :(得分:0)

如果你有一些常规枚举(只是序列值,而不是标志),你可以通过使用边界值快速实现:

enum t_MyEnum
{
    enum_begin

,   monday = enum_begin
,   tuesday
...
,   sunday  

,   enum_end
,   enum_items_cout = enum_end - enum_begin
};

更灵活的方式是实现一些枚举类型特征。

// traits
template<typename TEnum> class t_Integral
{
    public: using t_Type = int;
};

template<typename TEnum> class t_FirstItem;

template<typename TEnum> class t_LastItem;

template<typename TEnum> class t_ItemsCount
{
    public: static constexpr const ::std::size_t value
    {
        static_cast<::std::size_t>
        (
            static_cast<typename t_Integral<TEnum>::t_Type>(t_LastItem<TEnum>::value)
            -
            static_cast<typename t_Integral<TEnum>::t_Type>(t_FirstItem<TEnum>::value)
            +
            1
        )
    };
};

// enum
enum class t_MyEnum
:   ::std::uint16_t
{
    monday
,   tuesday
...
,   sunday
};

// specialize traits (can also be done to third-party enums)
template<> class t_Integral<t_MyEnum>
{
    public: using t_Type = ::std::uint16_t;
};

template<> class t_FirstItem<t_MyEnum>
{
    public: static constexpr const auto value{t_MyEnum::monday};
};

template<> class t_LastItem<t_MyEnum>
{
    public: static constexpr const auto value{t_MyEnum::sunday};
};

// now we have a generic way to get enum items count and can use it somehow...
::std::array< int, t_ItemsCount<t_MyEnum>::value > items;

枚举类型特征可以定义诸如枚举项目名称(作为字符串)和相应的转换函数,按类型分隔枚举(“顺序枚举”,“稀疏枚举”,“位标记枚举”),迭代枚举值,空值等等。

答案 2 :(得分:0)

如果你不介意依赖,你可以通过使用Qt框架以一种简单的方式解决这个问题。

查看QMetaEnum,尤其是keyCount函数。

这个用法由StackOverflow question的接受答案描述:您基本上必须将Q_ENUM(myEnum)宏附加到类中的枚举定义 myEnum myEnumClass

然后通过调用QMetaEnum myMetaEnum = QMetaEnum::fromType<myEnumClass::enumName>();

获得相应的QMetaEnum对象