1

Possible Duplicate:
How to use enums as flags in C++?

To explain what I'm trying to do, I'm trying to get a flags integer containing update check information, such as

int flags = keyPress | mouseClick | mouseMove; 

from my enum of events;

enum mEvents {
     keyPress = QEvent::KeyPress,
     keyRelease = QEvent::KeyRelease,
     mouseClick = QEvent::MouseButtonPress,
     mouseDoubleClick = QEvent::MouseButtonDblClick,
     mouseMove = QEvent::MouseMove
};

so that I can then check for what event types occurred like so;

void Lib::Update(QEvent *e) {
     if (e->type() == flags)
         stateManager->updateCurrentState(e);
}

What I'm trying to do is say, if the event type is any of the following in 'flags' then update. However, that isn't working. To be more precise, it works for key presses, but not for mouse clicks or move events.

So I'm wondering, if what I'd like to do is even possible, and if so how can I achieve this? (I'm pretty sure it is, I know SDL uses a similar flag system for it's screen creation) Any help is greatly appreciated.)

Community
  • 1
  • 1
Danran
  • 471
  • 1
  • 7
  • 21
  • 1
    thats not how it works. In this case, you will need to check event type each time with each value in that method. All you did — copied a part of another enumeration (QEvent::Type). Your idea will work only if each element of enumeration has per-byte value (0x1, 0x2, 0x4, 0x8, 0x10 etc.). Listed items don't have such values. – Pie_Jesu Sep 14 '12 at 19:23

2 Answers2

2

Right, because if you look at the documentation, those enumerated values are not all powers of two, so you can't use them as bit flags (well, you can, it just won't work if any of the bits overlap).

You're just copying the enumeration defined in QEvent, so really I don't see the point at all. You'll have to check for each type individually and they will not be coming to you as a combination of different values.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • The point was to try and get/find a way of getting extra flexibility checking for what can cause an update. I.e. one state could not use double clicking at all, whereas another could. I wanted to try and control this without my individual need to change it myself. – Danran Sep 14 '12 at 19:29
  • Not quite right. The enumerated values would need to be bit-wise independent. – N_A Sep 14 '12 at 19:31
  • @mydogisbox: Are you talking to me or Danran? – Ed S. Sep 14 '12 at 19:33
  • @EdS. You. The point being that 0x1100 and 0x0011 would be just fine for flags since they have no overlap. – N_A Sep 14 '12 at 19:35
  • @EdS. Still not quite right. There are other combinations of bits that are fine for flags. The issue comes when a particular flag doesn't have at least one unique bit. – N_A Sep 14 '12 at 19:40
  • @mydogisbox: I didn't edit it per your comment as my response is correct per the situation at hand. Sure, the two values you mention would work... until someone decides to add another member with the value `44` and the whole thing breaks. That would be a brain-dead, stupid way to implement a set of flags and no competent programmer would ever do such a thing. Besides, it doesn't apply to the question as many of the values defined in `QEvent::Type` do in fact overlap. – Ed S. Sep 14 '12 at 19:45
  • I've had times where I deliberately made the flags overlap for other reasons. Pertinent to this situation, the reason it won't work is because each flag doesn't have at least one unique bit. – N_A Sep 14 '12 at 19:52
  • @mydogisbox: Right... in which case, you didn't create a proper set of flags which can be combined arbitrarily... which is what the OP wants... so I really don't see your point. – Ed S. Sep 14 '12 at 20:06
  • @EdS. Sure it's not a proper set of flags. This "well, you can, it just won't work if any of the bits overlap" still isn't technically correct. It will work until flags don't each have their own bit. Probably not a good idea, but it would still work. – N_A Sep 14 '12 at 20:12
  • @mydogisbox: You seem to want to argue pedantically about details which are wholly irrelevant to the question. It's a waste of our time. Simply put; you should not be using these values as bit flags because they are not intended to be used in such a way and you cannot do so reliably, which is *completely obvious* when you look at their values. – Ed S. Sep 14 '12 at 20:14
  • @EdS. I'm not sure why you think that this is just pedantic. If the QEvent enum was fairly unlikely to change and the values he wanted from it happened to each have a bit unique within the set he wanted to use then it would work. That's entirely relevant. – N_A Sep 14 '12 at 20:25
  • @mydogisbox: So, in a theoretical world, where `QEvent::Type` will not change, and where `QEvent::Type` contains no values which would prevent it from being used as a unique set of flags, it would work. Yes, you're correct. Of course, that world does not exist, and you would be pretty dumb to rely on a third party library to not change, especially when you consider that said library does not document that these values should be used as flags. But ok, you're right. Glad that's sorted out. – Ed S. Sep 14 '12 at 20:28
  • @EdS. If you don't like that reason, then also think of the fact that this is a Q/A site and this answer might be used by someone else. Being "pedantically" correct is good because that means it will be useful outside of just this situation. – N_A Sep 14 '12 at 20:30
2

Enum values from here.

QEvent::KeyPress = 6 = 0x0110

QEvent::KeyRelease = 7 = 0x0111

QEvent::NonClientAreaMouseButtonPress = 174 = 0x10101110

QEvent::MouseButtonDblClick = 4 = 0x0100

QEvent::MouseMove = 5 = 0x0101

Notice how these line up bit-wise:

0x00000110

0x00000111

0x10101110

0x00000100

0x00000101

For this to work all of your flags would have to all have at least one bit not shared by other flags. Notice that

0x10101110 | 0x00000110 = 0x10101110 which is the first flag by itself.

so:

QEvent::NonClientAreaMouseButtonPress | QEvent::KeyPress

is indistinguishable from simply:

QEvent::NonClientAreaMouseButtonPress

N_A
  • 19,799
  • 4
  • 52
  • 98