非连续整数的C++枚举类型,最佳实现方法是什么?

3

按照我之前在这里描述的C++枚举模式,我尝试做类似的事情,但这次我想要使用的值序列不是由连续的整数数字组成。

这段代码显然是错误的:

class Rotations
{
    enum PossibleIndexes
    {
        ZERO,
        PLUS180,
        PLUS90,
        MINUS90
    };


    enum PossibleValues
    {
        ZERO= 0,
        PLUS180= 180,
        PLUS90= 90,
        MINUS90= -90
    };

    static int Count() { return MINUS90 + 1; }

    static PossibleValues Default(){ return ZERO; }
};

由于两个枚举类型内在元素之间存在冲突,因此我的问题是:如何最好地实现固定数量的硬编码旋转{0、180、90、-90},并具有默认和计数功能?


相关链接:https://dev59.com/YWUp5IYBdhLWcg3w3aZ1 - vsoftco
我找到了更好的解决方案,请查看解决方案 https://dev59.com/YWUp5IYBdhLWcg3w3aZ1#60216003。 - ixjxk
1
我找到了更好的解决方案,请查看解决方案 https://dev59.com/YWUp5IYBdhLWcg3w3aZ1#60216003。 - ixjxk
@ixjxk 你是否隐式创建了一个std::vector? - sergiol
3个回答

4

您可以始终保持一个静态的std::initializer_list,其中包含所有可能的值

namespace PossibleValues
{
    enum Type
    {
        ZERO= 0,
        PLUS180= 180,
        PLUS90= 90,
        MINUS90= -90
    };

    constexpr auto Values = {ZERO, PLUS180, PLUS90, MINUS90};
    size_t Count() { return Values.size(); }
    Type Default() { return *begin(Values); }
}

这种方法的额外好处是能够在 for 循环中迭代枚举值。
注意:我希望编译器至少能为枚举类生成全部代码。

为什么不呢?(如果我没记错的话)还有一个特定的徽章!尤其是如果你扩展并稍微修改你的答案,使其更具体地针对该帖子! - Adriano Repetti
Visual Studio无法编译该代码。 IntelliSense显示:“错误:无法推断'auto'类型”。在编译时,我在同一行中获得更多的错误:错误C2059:语法错误:'{',以及错误C2334:'{'之前的意外标记,跳过明显的函数体。 - sergiol
更新我的先前评论:我用std::initializer_list替换了auto。 IntelliSense显示“错误:命名空间“std”没有成员“initializer_list”。当编译时,我得到错误C2039:“initializer_list”不是“std”的成员 错误C4430:缺少类型说明符 - 假定为int。注意:C ++不支持d 错误C2146:语法错误:在标识符“ValuesOfPossibleValues”之前缺少“;” 错误C2059:语法错误:“{” 错误C2334:在“{”之前出现意外的标记;跳过明显的函数体。 - sergiol
尝试包含<initializer_list>。当您使用auto进行大括号初始化时,通常会自动包含此头文件,但如果您明确写出类型,则可能需要手动包含它。 - KABoissonneault
我尝试了 #include <initializer_list>,但仍然无法解析。 IntelliSense 给出以下错误提示:"Error: a member of type "const std::initializer_listCClass::Rotations::PossibleValues" cannot have an in-class initializer",而在编译时我得到了以下错误提示:error C2059: syntax error : '{',error C2334: unexpected token(s) preceding '{'; skipping apparent function body。 - sergiol
显示剩余10条评论

1

免责声明:我提到了我最近发布的一个开源库。

你可能想看看Better Enums。它可以避免你不必要的重复工作。

#include <enum.h>
ENUM(Rotations, int, ZERO = 0, PLUS180 = 180, PLUS90 = 90, MINUS90 = -90)

您可以这样访问常量的数量:

Rotations::_size

目前还没有内置的声明默认值的方法。然而,default构造函数当前是私有的,因此在创建Rotations值时必须提供一个值。这里展示了一种语法上“美观”的方式here——看看如何使用模板定义无效值。对于您的需求来说可能过于复杂。如果您尝试使用此库并对默认值有任何反馈,请让我知道。
我应该注意到计数和默认值是在编译时生成的。

啊,这看起来就像是我希望编译器做的事情。 很高兴看到已经有人做了我要做的工作。 - KABoissonneault

0

由于 Visual C++ 2010 编译工具包的限制(不完全符合 C++11 标准),我不得不屈服于较差的方法。

https://dev59.com/sHI95IYBdhLWcg3w3h_G#15961043 上的帖子还向我提供了一个有趣的获取值的方法。

class Rotations
{
public:
    typedef enum
    {
        ZERO= 0,
        PLUS180= 180,
        PLUS90 = 90,
        MINUS90 = -90
    }PossibleValues;

    static const PossibleValues PossibleValuesCollection(int index) {
        static const PossibleValues values[] = { ZERO, PLUS180, PLUS90, MINUS90 };

        return values[index];
    }

    static int Count() { return 4; }
    static PossibleValues Default(){ return ZERO; }
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接