• Advertisement
Sign in to follow this  

C++ Operator Overloading: Bitwise Operators & If-Check

This topic is 989 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys!

 

Since I need to use flags, but don't want to restrict myself to a maximum number of flags (Depending on the type I use: char, int, etc), I thought about creating some kind of templated<T> class storing T's in a list, on which operators can be used to make it look like standard C++ Bitwise flags.

(First things first: I don't know much about all that bitwise stuff)

 

Let's name my class "UFlag". How I want to be able to use it:

//Long way
UFlag<int> flag;
flag | 10 | 55;
if(flag & 10);
    //do stuff. This will be true, obviously.

//But also on the fast way:
myMethodTakingUFLAGasArgument(UFlag<int> | 10 | 55) //Somehow like this, so that I don't have to declare my variable first...

...

void myMethodTakingUFLAGasArgument(UFlag<int> f){
    UFlag<int> uf | 10; //I want also to be able to declare it like this... Saves one line.
    if(f & uf) ;//do stuff. should be true with the example-argument above.
    if(f & 55) ;//do stuff. should be true with the example-argument above.
}

Here is what I have right now: https://ideone.com/7jtnep

 

Unfortunately, not everything is working yet.

1 - I have not figured out yet how to apply the |/& operators in the same line as where I create the object.

2 - if checking doesnt work yet, as UFlag isnt a boolean.

 

How do I solve these two problems?

 

Kind regards,

Flyverse

 

Edit: Solved Problem#2.

Edited by Flyverse

Share this post


Link to post
Share on other sites
Advertisement

1. Normally the only operator that will return a reference to itself is an assignment operator like = or +=. The rest should take constant parameters (including "this") and return a new object. "c = a + b" does not alter the content of a or b.

 

UFlag<T> operator |(const UFlag<T> &b) const

 

should do the trick.

 

2. Implement explicit operator bool() const;

 

 

Share this post


Link to post
Share on other sites

operator bool ()const

{

 

  ... your boolean logic

}

 

it's the same way you can cast anything to another, i.e


struct Mask
{
  Mask(int v): 
  value(v)
  {
  }
  operator int()const{ return value;}

private:

int value;
};

 void SomeFunction(int i)
{

}

int main()
{
  Mask MyMask(5);

  SomeFunction(MyMask);

}

Share this post


Link to post
Share on other sites
Oh yeah, another advantage of using enums is that good IDEs (like Visual Studio) will properly visualize them in the debugger view.

They even innately visualize flags of enum values. So
EFileMode mode = EFileMode::Create | EFileMode::Truncate
will actually show up in the watch window as
mode  Create|Truncate
You can't get your wrapper type to do that properly.

Share this post


Link to post
Share on other sites

Second, your conditional idiom is slightly problematic even with plain integers, unless you particularly like getting lots of warnings:

if(f & uf) ;//do stuff. should be true with the example-argument above.
Prefer:
if((f & uf) != uf)

 

Why is the second preferred?

unsigned f  = (1 | 2 | 4 | 8);
unsigned uf = 4;

(f & uf) = uf
uf is non-zero
if(non-zero) = true

Share this post


Link to post
Share on other sites

 

Second, your conditional idiom is slightly problematic even with plain integers, unless you particularly like getting lots of warnings:

if(f & uf) ;//do stuff. should be true with the example-argument above.
Prefer:
if((f & uf) != uf)

 

Why is the second preferred?

 

I suspect it was supposed to be (f & uf) != 0, since the other version is definitely not equivalent. It prevents the implicit cast from unsigned to bool and all the potential compiler warnings that come with it (in VS it's usually something about runtime performance).

Edited by Trienco

Share this post


Link to post
Share on other sites

I suspect it was supposed to be (f & uf) != 0, since the other version is definitely not equivalent. It prevents the implicit cast from unsigned to bool and all the potential compiler warnings that come with it (in VS it's usually something about runtime performance).

 

I do not know what his intention was, however typically if you're testing flags and you want to ensure that all of the flags you are testing are set, you want (flags & flagsToTestFor) == something, as otherwise only having some of the flags in flagsToTestFor set can still return non-zero.

Edited by Washu

Share this post


Link to post
Share on other sites

Maybe I missed the objections but... why do you have to use flags and masks? Unless I have a lower-level component requiring it, I'd stay away from them.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement