Solved Can't reset QFlag in simple class
-
Hi
I think its due to using a value of zero for one of the enums.try with
enum MyFlag { Yes = 1, // default No =2 };
then it looks as expected
-
@mrjj huh now it works :)
thank you! -
Hi,
It is shown in and explained in the QFlags that each item of your flags need to have a different value (1 -> 2 -> 4 -> 8 -> etc.) that can be ORed otherwise you cannot establish which was set. You can do that using a binary format for your number, it will make things clearer.
-
@SGaist thank you!
But it is always difficult for me to read documentation about something new that I don't have any idea. It becomes much easier when I already have some representation about studied topic.
As example I've read both this and that but nothing helped me to solve my task. I'm like a slowpoke :)
But now when I know that QFlag is something like a list of boolean variables I can match documentation with my needs. I always search "how to solve my problem" in Internet and only then I disturb people from communities.
This is just my excuses so you would not think that I don't do anything to solve my problem by myself :)I really appreciate forum's people help because you save a lot of time and nerves and honestly saying I would have never learned programming (Matlab and C/C++) if there were not such communities.
-
Hi
Yes its like a list
but to make it take up far less space, it uses bits instead of a bool.
So basically QFlags helps you get/and set the bits.You know for programming a value can also be shown as binary 0 and 1 ?
When you OR something, then just one of the bit has to be set then it becomes set in the result too.
0 1 0 1 OR 0 1 1 0 ------- 0 1 1 1
with AND operator both bits must be set to be set in the result.
Thats how QFlags works interinally
if we look at
Q_DECL_RELAXED_CONSTEXPR inline QFlags &setFlag(Enum flag, bool on = true) noexcept { return on ? (*this |= flag) : (*this &= ~Int(flag)); }
then it says
if (on is true )
value = value OR flag ( in your case yes )
else if on is false ( to turn off )
value = value AND (negative) flagthe last part is taking out the bits that belong to the value for the flag.
So AND / OR is not that difficult to understand at a high level as it simply
manipulate the values as bits. -
@mrjj thank you!
I understood something but some interesting things I don't. Here what I get.
Yes I understand byte/bitThis:
on ? (*this |= flag) : (*this &= ~Int(flag));
is equal to:
if ( on == true ){ *this = (*this || flag); } else { *this = (*this &~ Int(flag)); }
right?
If so then to understand the mathematics I need to understand what in bit representation is:*this
,flag
,Int(flag)
In my caseflag
is equal to 1 right ( enum MyFlag { Yes = 1} )? in bit representation 0001
But what is in*this
before assigning anything (operator =) and what functionInt()
does? simply convertsflag
to integer? as I know this type of casting doesn't change bits of the number it simply tells "these bits should be read as int"
Something like that:)||________________
By the way how to turn on notifications when somebody answers me or writes in topic created by me? -
Yes odd syntax is called Conditional ternary operator:
but is just a one liner if else.(condition) ? (if_true) : (if_false)
The *this de reference the this pointer.
so its what it points to.
This is done to trigger the operator = which QFlags have overloaded.
so its a way to assign the value to it self using =the Int() is a type cast like (Int)flag;
But its a bit more if we look at source#if defined(Q_CC_MSVC) || defined(Q_CLANG_QDOC) // see above for MSVC // the definition below is too complex for qdoc typedef int Int; #else typedef typename std::conditional< std::is_unsigned<typename std::underlying_type<Enum>::type>::value, unsigned int, signed int >::type Int; #endif
so when not MSVC compiler it also checks the type
And if you think that looks strange, you are right :)
Its c++ templates and while really useful, its also
often ugly and unreadable. So ignore it until later in your training. -
@mrjj all the things that depend on the compiler features are far outside of my current possibilities :)
So I think I begin to understand the magic behind QFlag.
returned value is of typebool
andbool
is not a single bit but rather a byte (maybe few bytes). So any numbers written inYes
except zero in this expression:*this || flag
returnes some byte (bytes) where even a single (or more) bits is not zero. A
bool
which has even a single (or more) non zero bit should returntrue
right?
And I believe that behind this dark veil:*this &~ Int(flag)
are hidden all zeroed bits :)
By the way is it necessary to assign numbers to enum definitions (Yes, No etc) that are equal the power of 2 (1, 2, 4, 8, 16 ...)? as in many examples
-
Ok that's good :)
maybe you are ready for
https://www.youtube.com/watch?v=TKEaakjKrMc
Bitwise AND / ORActually the dark veil:
is using AND and BINARY NOT
to remove the bits for a flagYes, you must use power of 2 values as else some of the values will have
overlapping bit representation and things get funny when you combine certain flags. -
@mrjj thank you
Video helped me to remember what XOR. Also now it I understand how to easilly transform binary data representation to decimals :)