我遇到了一个我认为无法有效解决问题的问题。我有一堆标志(FLAG_1和FLAG_2下面)。我想重置其中一个并将结果传递给一个函数。如果没有位字段,我可以简单地写一下:
BYTE flags=FLAG_1 | FLAG_2; // both flags set
func(flags & ~FLAG_2); // preserve Flags in the current scope and pass in "Flags minus FLAG_2"
在这种情况下语法很好但在其他地方使用Flags时很麻烦(例如在IF中)。
使用位字段,相同的代码变得更加冗长:
struct TBitField{
unsigned flag1:1;
unsigned flag2:1;
};
TBitField bf={ true, true }; // both flags set
TBitField tmp=bf;
tmp.flag2=false;
func(tmp);
在这种情况下采用丑陋的方法,但在其他地方使用位字段时很方便。
因此,是否存在修改位域并在一行中传递它的折衷方案?
TBitField bf={ true, true }; // both flags set
func( bf - FLAG_2 ); // my idealized pseudo-syntax...
提前致谢。
答案 0 :(得分:2)
您可以在比特字段中定义方法 - 它几乎是正常struct
,即class
。例如,您可以添加清除和设置位的方法:
struct TBitField {
unsigned flag1:1;
unsigned flag2:1;
TBitField clr2() {
TBitField tmp = *this;
tmp.flag2 = false;
return tmp;
}
};
然后你用它作为例如:
func( bf.clr2() );
答案 1 :(得分:1)
我可以想到几个选项,实现这个"语法糖",就像你所说的那样。我将简要介绍一种可能的解决方案。它不是唯一的一个。
鉴于您对struct TBitField
的定义,请定义另一个类。枚举类很好用
enum class bits {bit_0, bit_1, bit_2 ... }; // And so on.
现在,重载+和 - 运算符。像这样:
TBitField operator+(const TBitField &a, bits bit_number)
{
// ...
}
和
TBitField operator-(const TBitField &a, bits bit_number)
{
// ...
}
现在,您可以使用所需的语法:
func( bf - bits::bit_2 );
这将调用相应的operator
。这两个运算符的实现应该是显而易见的,而且没有必要在这里详细说明。
您甚至可以选择放弃帮助类,只需定义:
TBitField operator+(const TBitField &a, int bit_number)
{
// ...
}
TBitField operator-(const TBitField &a, int bit_number)
{
// ...
}
然后简单地使用:
func( bf - 2 );
虽然这看起来有些令人困惑,但这就是为什么我认为使用显式助手类更好。
这两种方法都可能引入一点编译器膨胀。为了解决这个问题,对于大多数编译器,我建议将两个运算符定义为inline
,并定义将右值引用作为参数的重载版本。