有没有办法改变枚举设置其常量值的方式?通常它会增加1但我想应用其他规则。在PAWN中,这将起作用
enum (<<=1) {
a = 1,//0b001
b,//0b010
c//0b100
}
有没有办法在C ++中执行此操作?
答案 0 :(得分:4)
不是自动的,但您可以手动指定每个值
enum X {
a = 0x01,
b = 0x02,
c = 0x04
};
答案 1 :(得分: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 :(得分: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
答案 3 :(得分: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
};
我知道,它并不理想,但它避免了明确的文字常量。一些肮脏的东西可以用宏来隐藏,你可能会或可能不会认为这是一件好事。
答案 4 :(得分: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 中的标准,其中引入了二进制文字。
否则,您可以使用shift运算符指定位位置:
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
};
答案 5 :(得分:0)
窃取伟大的idea of 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>;
您正在寻找的枚举结果(see here)。好吧,shifted
不是枚举,而是结构,希望它不重要。
定义不同的增量函数,您可以自动增加自动增加的枚举族,只要它们都只有managed_enum
(a
,{b
{ {1}},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>>;