应用关于如何递增枚举的规则

问题描述 投票:0回答:6

有没有办法改变枚举设置其常量值的方式?通常它会增加一,但我想应用另一条规则。在 PAWN 中这会起作用

enum (<<=1) {
 a = 1,//0b001
 b,//0b010
 c//0b100
}

有没有办法在 C++ 中做到这一点?

c++ enums increment rule
6个回答
4
投票

不会自动,但您可以手动指定每个值:

enum X {
  a = 0x01,
  b = 0x02,
  c = 0x04
};

3
投票

您可以使用模板元编程自动执行此转换过程:

template<int by>
struct OneShlBy {
    enum { Value = OneShlBy<by - 1>::Value << 1 };
};

template<>
struct OneShlBy<0> {
    enum { Value = 1 };
};

enum X {
    a = OneShlBy<0>::Value,
    b = OneShlBy<1>::Value,
    c = OneShlBy<2>::Value
};

2
投票

一种方法,假设是 C++11,是

constexpr int func(int x)
{
     return x << 1;
}

enum X
{
   a = 1,
   b = func(a),
   c = func(b)
};

然后可以使用

func()
来实现连续命名值之间的任何您喜欢的关系。

在 C++11 之前,替代方案可能包括

enum X
{
   a = 1,
   b = a << 1,
   c = b << 1
};

或(使用宏)

#define func(x) x << 1
enum X
{
   a = 1,
   b = func(a),
   c = func(b)
};
#undef func

1
投票

您给出的特定示例(枚举本质上是单词中的标志)的一种常见方法是使用两个枚举,一个用于位索引,第二个枚举用于实际位值:

enum {
   b_a,             // 0
   b_b,             // 1
   b_c,             // 2
   b_d,             // 3
};

enum {
   a = 1 << b_a,    // 1
   b = 1 << b_b,    // 2
   c = 1 << b_c     // 4
   d = 1 << b_d     // 8
};

我知道这并不理想,但它避免了显式的文字常量。一些肮脏的事情可以用宏来隐藏,你可能会或可能不会认为这是一件好事。


0
投票

你正在做的事情非常好:

#include <iostream>

enum x {
   a = 0b001
 , b = 0b010
 , c = 0b100
};

int main()
{
    std::cout << x::a << '\n';
    std::cout << x::b << '\n';
    std::cout << x::c << '\n';
}

注意:这只是引入二进制文字的C++14中的标准。

否则,您可以使用移位运算符来指定位位置:

enum x {
      a = 1 << 0
    , b = 1 << 1
    , c = 1 << 2
};

如果您希望节省一些维护工作,另一种可能性是根据之前定义的

enum
来定义每个
enums

enum x {
      a = 1
    , b = a << 1
    , c = b << 1
    , d = c << 1
    , e = d << 1
};

这意味着您可以相对轻松地在中间添加一个元素:

enum x {
      a = 1
    , b = a << 1
    , z = b << 1 // new element added
    , c = z << 1 // only need to adjust one other
    , d = c << 1
    , e = d << 1
};

0
投票

窃取 Rob 的伟大想法,有一种方法可以指定如何增加枚举的值,虽然这不是很自动,但只要你的枚举始终具有相同的字段,你就可以做这样的事情:

template <typename T, T(*INC)(const T), T start = {}>
struct managed_enum
{
    enum
    {
        a = start,
        b = INC(a),
        c = INC(b),
    };
};

使用此模板,您可以执行以下操作:

template<typename T>
constexpr T shift_left(const T value) { return value << 1; }

using shifted = managed_enum<int, shift_left<int>, 1>;

您要查找的枚举上的哪些结果(参见此处)。好吧,

shifted
不是一个枚举,而是一个结构体,希望这并不重要。

定义不同的增量函数,你可以让不同的枚举系列自动增加,只要它们都只有

managed_enum
的三个值(
a
b
c
):

template<typename T>
constexpr T shift_left(const T value) { return value << 1; }

template<typename T>
constexpr T increment(const T value) { return value + 1; }

template<typename T>
constexpr T bicrement(const T value) { return value + 2; }

using shifted   = managed_enum<int, shift_left<int>, 1>;
using increment = managed_enum<int, increment<int>>;
using bicrement = managed_enum<int, bicrement<int>>;
© www.soinside.com 2019 - 2024. All rights reserved.