I've run into a problem that I feel to be solving inefficiently. I have a bunch of flags (below FLAG_1 and FLAG_2). I want to reset one of them and pass the result into a function. Without a bit field, I could simply write:
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"
Nice syntax in this situation but cumbersome when working with Flags elsewhere (eg in IFs).
Using a bit field the same code becomes more verbose:
struct TBitField{
unsigned flag1:1;
unsigned flag2:1;
};
TBitField bf={ true, true }; // both flags set
TBitField tmp=bf;
tmp.flag2=false;
func(tmp);
Ugly approach in this situation but handy when working with the bit field elsewhere.
Hence, is there a compromise to modify the bit field and pass it over in just one line?
TBitField bf={ true, true }; // both flags set
func( bf - FLAG_2 ); // my idealized pseudo-syntax...
Thanks in advance.
You are allowed to define methods in your bitfield - it's pretty much a normal struct
, which is a class
. You could for example add methods to clear and set bits:
struct TBitField {
unsigned flag1:1;
unsigned flag2:1;
TBitField clr2() {
TBitField tmp = *this;
tmp.flag2 = false;
return tmp;
}
};
Then you use it as for example:
func( bf.clr2() );
There are several options I can think of, to implement this "syntactical sugar", as you call it. I'll give a brief outline of one such possible solution. It's not the only one.
Given your definition of a struct TBitField
, define another class. An enum class will work well
enum class bits {bit_0, bit_1, bit_2 ... }; // And so on.
Now, overload the + and - operators. Something like this:
TBitField operator+(const TBitField &a, bits bit_number)
{
// ...
}
and
TBitField operator-(const TBitField &a, bits bit_number)
{
// ...
}
Now, you can use your desired syntax:
func( bf - bits::bit_2 );
And this will invoke the corresponding operator
. The implementation of the two operators should be obvious, and not necessary to spell out, here.
You may even choose to forego a helper class, and simply define:
TBitField operator+(const TBitField &a, int bit_number)
{
// ...
}
TBitField operator-(const TBitField &a, int bit_number)
{
// ...
}
And then simply use:
func( bf - 2 );
Although that looks slightly confusing, that's why I think that using an explicit helper class is better.
Either approach will likely introduce a little bit of compiler bloat. To remedy this, with most compilers I'd suggest defining both operators as inline
, and also define overloaded versions that take an rvalue reference as a parameter.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.