我在c中创建一个枚举,使得使用二进制标志的有限状态机.看起来像:
enum VStates { NEUTRAL = 0x00000000,// 000000 // Physical Status DRY = 0x00000001,// 000001 WET = 0x00000002,// 000010 HOT = 0x00000004,// 000100 COLD = 0x00000008,// 001000 BURNED = 0x00000016,// etc.. FROZEN = 0x00000032,EROS = 0x00000064,// THANATOS = 0x00000128,// SLEEP = 0x00000256,STUNNED = 0x00000512,PARALYZED = 0x00001024,POISONED = 0x00002048,// BLIND = 0x00004096,SOFT = 0x00008192,// Flexible TOUGH = 0x00016384,// Resistent MAGNETIZED = 0x00032768,POSSEDERUNT = 0x00131072,// // Mental Status ANGRY = 0x00262144,DRUGGED = 0x00524288,// Drugs Meaning HORNY = 0x01048576,// Sexual Meaning // Material Status MetaL = 0x02097152,WOOD = 0x04194304,GLASS = 0x08388608,AIR = 0x16777216,EARTH = 0x33554432,DUST = 0x67108864,LIGHT = 0x134217728,SHADOW = 0x268435456,WATER = 0x536870912,// Total Status PROTECTED = 0x1073741824,INVULNERABLE = 0x2147483648 };
一些状态是不兼容的,所以我使用Bitwise运算符来管理它们.现在,我的编译器说:
warning: integer constant is too large for 'long' type
解决方法
(注意:为了使我的答案完整,我将添加一些我没有时间注意到的东西,但其他人已经指出:你使用0x前缀,这意味着你的数字将被解释为十六进制,他们不会实际上是两个的权力,你的bitflag测试不会有效!)
如果您的枚举失去控制权,则不要使用枚举类型.使用像std::bitset
这样的东西.那么你的枚举只能是一个简单的编号的名字列表,用于在集合中的位的位置…你将不会按顺序排列你的枚举空间!
例如:
enum VState { NEUTRAL,DRY,WET,COLD,BURNED,FROZEN,/* ... */ VState_Max }; bitset<VState_Max> state; state[COLD] = true; if (state[COLD]) { cout << "I am cold\n"; }
现在你的枚举只是一个小而可维护的数字,你不用担心在一个64位的平台上或者什么都没有.
我注意到,在你的原始例子中,你给了一个值为“0”的中性.如果你的意图是有可能使用它与其他东西的组合…,例如能够被state = NEUTRAL |不可接受| SHADOW和单独测试NEUTRAL,以前没有工作.现在,您只需将其保留在枚举位置的索引中.
但是,如果它打算作为“没有设置”的名称,那么你将从枚举中删除它,而是测试没有设置的位:
if (state.none()) { // we are in the "NEUTRAL" state of nothing set... }
…如果你想将所有的位设置为false,你可以:
state.reset();