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!


  • Lifetime Qt Champion

    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!



  • Something that you have to remember is that an enum is an enumeration of constants, not a container. You cannot directly check for membership in an enum.

    Mike



  • @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
    }
    

  • Qt Champions 2016

    @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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.