Applying the rule on how to increase enumeration

Is there a way to change how an enumeration sets the values ​​of its constants? It usually increases by one, but I want to apply a different rule. At PAWN, this will work

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

Is there a way to do this in C ++?

+4
source share
6 answers

not automatically, but you can manually specify each value

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

You can automate this offset process using metaprogramming patterns:

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
};
+3
source

, , ++ 11,

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

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

func() , .

++ 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
+2

, (, ), : :

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
};

, , . , .

+1

, , :

#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';
}

: ++ 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

, , , , , , - :

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 , , , .

Defining the different functions of the increment, you can automatically increase the different families of transfers, as long as they all have only three values 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>>;
0
source

All Articles