Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to loop over all enums?
Forum Updated to NodeBB v4.3 + New Features

How to loop over all enums?

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 6 Posters 6.5k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Rattata1234R Offline
    Rattata1234R Offline
    Rattata1234
    wrote on last edited by
    #1

    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!

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      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.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      1
      • R Offline
        R Offline
        rafael
        wrote on last edited by
        #3
         // 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";
               }
            }
        
        1 Reply Last reply
        1
        • Rattata1234R Offline
          Rattata1234R Offline
          Rattata1234
          wrote on last edited by
          #4

          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!

          1 Reply Last reply
          0
          • M Offline
            M Offline
            mjsurette
            wrote on last edited by
            #5

            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

            Rattata1234R 1 Reply Last reply
            1
            • M mjsurette

              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

              Rattata1234R Offline
              Rattata1234R Offline
              Rattata1234
              wrote on last edited by
              #6

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

              1 Reply Last reply
              0
              • M Offline
                M Offline
                mjsurette
                wrote on last edited by
                #7

                @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

                kshegunovK 1 Reply Last reply
                0
                • VRoninV Offline
                  VRoninV Offline
                  VRonin
                  wrote on last edited by VRonin
                  #8

                  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
                  }
                  

                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                  ~Napoleon Bonaparte

                  On a crusade to banish setIndexWidget() from the holy land of Qt

                  1 Reply Last reply
                  0
                  • M mjsurette

                    @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

                    kshegunovK Offline
                    kshegunovK Offline
                    kshegunov
                    Moderators
                    wrote on last edited by kshegunov
                    #9

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

                    Read and abide by the Qt Code of Conduct

                    1 Reply Last reply
                    2

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved