How to loop over all enums?
-
Hello again!
Soo the title might not be that good but i hope my code can explain my problem.
I have an enum class:enum class CardID{ firstID, secondID, thirdID };
And i have a scruct with a QVector
struct human{ CardID id; QString Name; }; QVector<human> humans;
I want check if the id i got is the same as the id in my enum class so i want to loop over all "CardIDs"
foreach(human myVar, humans) { if(myVar.id == scannedID) //do something }
But this doesn't work because my humans is empty. What mistake did i make?
Thanks guys!
-
Hi,
Like you wrote,
humans
is empty so your loop won't do anything because there's nothing to do.You need to add
human
objects to your vector before your loop does anything.If you want to test each possible CardID, then using a switch statement would be clearer.
-
// input some value to your vector human h; h.id = CardID::firstID; h.Name = "test one"; humans.push_back(h); h.id = CardID::secondID; h.Name = "test two"; humans.push_back(h); foreach(human myVar, humans) { // can use a switch case statement if(myVar.id == CardID::firstID) { qDebug() << "first id match"; } if(myVar.id == CardID::secondID) { qDebug() << "second id match"; } }
-
Soo thank you guys! I thought that these vectors work somehow different^^ But i tried something else now. All i want to know is if the scannedID is in my enum, So i cast the scannedID to CardID. If the scannedID is not a CardID then i'll get a zero back, right? So all i have to do is check in my if statement if the scannedID is not zero.
CardID id; .... id= CardID( scannID() ); //if it's not a CardID: id = 0 if( int ( id ) != 0) { //card accepted } else { //not accepted }
Is this approach accaptable? Or is there something else i can do? Because i actually don't need to know the id, i just want to know if the id is in my enum. I hope you can understand^^
Thank you guys for your answers though. They gave me some ideas!
-
@mjsurette
you are right, after some research i found this:enum value is valid in C++ if it falls in range [A, B], which is defined by the standard rule below. So in case of enum X { A = 1, B = 3 }, the value of 2 is considered a valid enum value.
I guess i have to check all enums in my if statement.
Thanks! -
@Rattata1234 said:
enum value is valid in C++ if it falls in range [A, B], which is defined by the standard rule below. So in case of enum X { A = 1, B = 3 }, the value of 2 is considered a valid enum value.
I guess i have to check all enums in my if statement.
You may find that a switch statement is easier to write, understand, and maintain.
enum X{A=1, B=3}; switch (id) { case int(X::A): case int(X::B): validID= true; break; default: validID= false; }
Mike
-
Generally speaking you can't do it in C++ but the meta object system of Qt can handle this via QMetaEnum
class EnumDefinitions{ Q_GADGET EnumDefinitions()=delete; virtual ~EnumDefinitions()=0 {} public: enum class CardID{ firstID, secondID, thirdID }; Q_ENUM(CardID) }
const QMetaEnum metaCardID = QMetaEnum::fromType<EnumDefinitions::CardID>(); for (int i=0;i<metaCardID.keyCount();++i){ if(myVar.id == metaCardID.value(i)) //do something }
-
@mjsurette said in How to loop over all enums?:
You may find that a switch statement is easier to write, understand, and maintain.
enum X{A=1, B=3}; switch (id) { case int(X::A): case int(X::B): validID= true; break; default: validID= false; }
There's no need to have static casts here. Switch works for integral types, which enums are:
switch (id) { case CardID::firstID: case CardID::secondID: case CardID::thirdID: // In enum break; default: // Not in enum }
However, the simplest way (provided your enum's values are consecutive) is to just use plain ol'
if
:bool valid = id >= CardID::firstID && id <= CardID::thirdID;
Kind regards.