位掩码 switch 语句
我的项目的一部分中有这段代码:
enum myEnum
{
invalid = -1,
val1 = 1,
val2 = 2,
val3 = 4
};
int bitmask = val1 | val3;
if(bitmask & val1)
...
if(bitmask & val2)
...
if(bitmask & val3)
...
这很好,并且工作完美,但我一直想知道是否可以通过开关来完成。我在想一些类似的事情:
int checkMask(int& mask)
{
for(int i = 0; mask; mask &= ~(1 << i++))
{
if(mask & (1 << i))
{
int ret = mask & (1 << i);
mask &= ~ret;
return ret;
}
}
return invalid;
}
#define START_BITMASK_SWITCH(x) int xcopy = x; while(xcopy) { switch(checkMask(xcopy))
#define END_BITMASK_SWITCH };
int bitmask = val1 | val3;
START_BITMASK_SWITCH(bitmask)
{
case val1:
...
break;
case val2:
...
break;
case val3:
...
break;
}
END_BITMASK_SWITCH
所以我的问题是:
I have this code in a section of my project:
enum myEnum
{
invalid = -1,
val1 = 1,
val2 = 2,
val3 = 4
};
int bitmask = val1 | val3;
if(bitmask & val1)
...
if(bitmask & val2)
...
if(bitmask & val3)
...
This is fine, and it works perfectly, but i've always wondered if it could be done with a switch. I was thinking something along the lines this:
int checkMask(int& mask)
{
for(int i = 0; mask; mask &= ~(1 << i++))
{
if(mask & (1 << i))
{
int ret = mask & (1 << i);
mask &= ~ret;
return ret;
}
}
return invalid;
}
#define START_BITMASK_SWITCH(x) int xcopy = x; while(xcopy) { switch(checkMask(xcopy))
#define END_BITMASK_SWITCH };
int bitmask = val1 | val3;
START_BITMASK_SWITCH(bitmask)
{
case val1:
...
break;
case val2:
...
break;
case val3:
...
break;
}
END_BITMASK_SWITCH
so my questions are:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
不,这不是一个干净的解决方案,对于您的上下文,您可以避免混合
#define
和函数。如果您想要switch()
,您可以尝试以下解决方案:No it's not a clean solution and for your context, you can avoid mixing
#define
and functions. You can try below solution, if you wantswitch()
:不,这(显然)不是一个干净的解决方案。您的原始代码很简单,没有循环,并且不涉及向语言添加奇怪结构的特殊情况“秘密”宏。
我所说的“奇怪的构造”是指
START_BITMASK_SWITCH()
/END_BITMASK_SWITCH
宏,它:这对您的解决方案没有任何好处,它所做的只是增加膨胀和开销(无论是在代码大小方面,以及复杂性和运行时性能)只是为了满足出于某种原因想要使用
switch
来做一些不太适合做的事情的渴望。显然,这是非常主观的,但你确实问过。
No, it is (obviously) not a clean solution. Your original code was straight-forward, didn't loop, and didn't involve special-case "secret" macros that add weird constructs to the language.
By "weird construct", I meant the
START_BITMASK_SWITCH()
/END_BITMASK_SWITCH
macros, which:There's no benefit to your solution, all it does is add bloat and overhead (both in terms of code size, and complexity, and run-time performance) just to scratch that itch of for some reason wanting to use a
switch
to do something that it's not very well-suited to do.Obviously, this is highly subjective, but you did ask.
我看到了几个问题:
if ((bitmask & (val2 | val3)) == val2)
)。 ,简单得多 方式:
I see several problems:
if ((bitmask & (val2 | val3)) == val2)
)It can also be done in a much, much simpler way:
如果需要的话,位掩码只是一个布尔数组,而您的枚举就是索引。你能切换一个bool数组吗?不,你不能,因为它可以同时代表多个状态。您只能像使用任何整数一样切换整体位掩码。
A bitmask is just an array of bools if you want, and your enum are the indices. Can you switch over an array of bool? No you can't, because it can represent multiple states at the same time. You could only switch over the overall bitmask like with any integer.
您可以创建一个 foreach 构造,在其中迭代位掩码的位并提供一个带有 switch 语句的函数。
You could make a foreach construct where you iterate through the bits of your bitmask and provide a function with a switch statement in it.
当然可以,如果那是你真正想要的。如前所述,只有有限的情况,也许没有,您可能需要这样做。但你可以。
Of course you can, if that's what you really want. As mentioned there are only limited cases, maybe none, where you may ever need to. But you can.
使用 C++0x 强枚举 会更好,那么您可以使用
Position::ALPHA
和Flag::ALPHA
进行更清晰的命名。您还可以使用constexpr
安全地对您的 Flag 值进行位掩码。This is nicer with C++0x strong enums, then you can have
Position::ALPHA
andFlag::ALPHA
for clearer naming. You can also useconstexpr
to safely bitmask your Flag values.