Partage
  • Partager sur Facebook
  • Partager sur Twitter

Inclure une énumération dans une autre

Sujet résolu
    29 août 2014 à 14:11:30

    Bonjour. :)

    Je possède dans mon appli les 2 énumérations suivantes :

    enum { BOUTON1, BOUTON2, NB_BOUTONS };
    
    enum { BOUTON1, BOUTON2, CLIQUABLE, NB_CLIQUABLES };

    Seulement à chaque fois que je rajoute un bouton, il me faut le rajouter aux deux énumérations, j'aurais voulu une solution plus sure.

    J'ai donc pensé à utiliser des valeurs explicites :

    enum { BOUTON1, BOUTON2, NB_BOUTONS };
    
    enum { CLIQUABLE = NB_BOUTONS, NB_CLIQUABLES };

    De ce fait les valeurs sont incrémentées à partir de NB_BOUTONS (si je ne me trompe pas :euh: ).

    Seulement, j'ai utilisé un type pour la seconde énumération :

    enum Cliaquable_t { BOUTON1, BOUTON2, CLIQUABLE, NB_CLIQUABLES };

    Du coup les boutons ne sont plus considérés comme cliquables.

    Si vous avez des idées, des propositions.

    Merci !! ;)

    -
    Edité par Maluna34 29 août 2014 à 14:14:50

    • Partager sur Facebook
    • Partager sur Twitter
      29 août 2014 à 14:45:46

      Maluna34 a écrit:

      Bonjour. :)

      Je possède dans mon appli les 2 énumérations suivantes :

      enum { BOUTON1, BOUTON2, NB_BOUTONS };
      
      enum { BOUTON1, BOUTON2, CLIQUABLE, NB_CLIQUABLES };

      Euuhhh, et ca compile ??? Si tu n'utilise pas les énumérations fortement typées de C++11, le simple fait de retrouver la même valeur énumérée dans deux énumération distinctes est très clairement de nature à empêcher la compilation si, pour une raison ou une autre, ces deux énumérations finissent par être inclue dans le même fichier...

      Seulement à chaque fois que je rajoute un bouton, il me faut le rajouter aux deux énumérations, j'aurais voulu une solution plus sure.

      J'ai donc pensé à utiliser des valeurs explicites :

      enum { BOUTON1, BOUTON2, NB_BOUTONS };
      
      enum { CLIQUABLE = NB_BOUTONS, NB_CLIQUABLES };

      De ce fait les valeurs sont incrémentées à partir de NB_BOUTONS (si je ne me trompe pas :euh: ).

      Seulement, j'ai utilisé un type pour la seconde énumération :

      enum Cliaquable_t { BOUTON1, BOUTON2, CLIQUABLE, NB_CLIQUABLES };

      Du coup les boutons ne sont plus considérés comme cliquables.

      Si vous avez des idées, des propositions.

      Merci !! ;)

      Pas pour faire en sorte de rajouter des valeurs énumérées dans deux énumérations, mais une solution sans doute beaucoup plus intéressante : revoir ta conception...

      De toute évidence, tu semble déterminé à utiliser cette énumération comme support à du RTTI (Run Type Type Identification) pour en arriver à écrire un code qui finira tôt ou tard à ressembler à quelque chose comme

      void someFunction(Widget * w){
          switch(w.type()){
              case BOUTON1 :
                  dynamic_cast<Derivee1*>(w)->foo();
                  break;
              case BOUTON2 :
                  dynamic_cast<Derivee2*>(w)->bar();
                  break;
              case CLICKABLE :
                  dynamic_cast<Derivee3*>(w)->doSomething();
                  break;
              case SELECTABLE:
                  dynamic_cast<Derivee4*>(w)->doOtherthing();
                  break;
          }
      }

      Cette approche ne peut que d'apporter un max de cheveux blancs, car l'OCP n'est absolument respecté.  Avec la multiplication de ce genre de code, tu peux t'attendre, chaque fois que tu voudra ajouter une valeur énumérée, à oublier systématiquement un ou deux endroits où il faut prendre cette nouvelle valeur en compte dans ton code :p

      • Partager sur Facebook
      • Partager sur Twitter
      Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
        29 août 2014 à 14:57:45

        koala01 a écrit:

        Euuhhh, et ca compile ??? Si tu n'utilise pas les énumérations fortement typées de C++11, le simple fait de retrouver la même valeur énumérée dans deux énumération distinctes est très clairement de nature à empêcher la compilation si, pour une raison ou une autre, ces deux énumérations finissent par être inclue dans le même fichier...

        Ah oui, j'ai oublié de préciser que du coup, j'ai des noms différents. :D Là c'est pour bien faire comprendre la conception.

        koala01 a écrit:

        Cette approche ne peut que d'apporter un max de cheveux blancs, car l'OCP n'est absolument respecté.  Avec la multiplication de ce genre de code, tu peux t'attendre, chaque fois que tu voudra ajouter une valeur énumérée, à oublier systématiquement un ou deux endroits où il faut prendre cette nouvelle valeur en compte dans ton code :p

        Non je ne pourrai pas oublier de prendre cette valeur en compte, parce que justement un bouton est un objet cliquable, donc je veux dans mon tableau de cliquables mettre tous mes boutons.

        Pour le moment je répète la liste, mais justement ce que je veux éviter, ce sont les incohérences. N'y a-t-il pas moyen de jouer avec les énumérations ?

        Après je veux bien concevoir que ma conception est mauvaise. :D

        -
        Edité par Maluna34 29 août 2014 à 14:59:45

        • Partager sur Facebook
        • Partager sur Twitter
          29 août 2014 à 15:24:14

          Maluna34 a écrit:

          Non je ne pourrai pas oublier de prendre cette valeur en compte, parce que justement un bouton est un objet cliquable, donc je veux dans mon tableau de cliquables mettre tous mes boutons.

          Tu n'as pas compris ce que je voulais dire...

          Qui dit énumération dit, forcément, test (sans doute à choix multiple) lors de l'utilisation de cette énumération, sans doute sous la forme que je t'ai présentée lors de ma première réponse.

          Le gros problème, c'est que tu vas forcément finir à terme par te retrouver avec ce genre de tests un peu partout dans ton projet.  Tu le retrouveras peut-être dix fois au début, mais, à la longue, tu retrouvera ce test (avec quelques adaptations, forcément) vingt, cinquante ou cent fois dans l'ensemble de ton projet.

          Or, si tu décide de rajouter une valeur énumérée, tu devras veiller à ce que cette nouvelle valeur énumérée soit prise en comptepour chaque utilisation de ton énumération,ou, si tu préfères, chaque fois qu'une décision devra être prise en fonction de la valeur énumérée observée, ce qui implique que, si tu as créé 100 tests sur tes valeurs pour répondre à tes différents besoins, tu devra mettre ces 100 tests à jour.

          La loi de murphy aidant, tu peux avoir la certitude d'en oublier de manière systématique, et cela ne manquera pas de te poser quelques soucis ;)

          • Partager sur Facebook
          • Partager sur Twitter
          Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
            29 août 2014 à 16:16:13

            Oui mais le soucis que tu décris, je l'aurait même en laissant les 2 énumérations séparées.
            • Partager sur Facebook
            • Partager sur Twitter
              29 août 2014 à 23:01:25

              Donc la réponse est 0 enum, CQFD de koala01.

              On recommence, POURQUOI cet enum très peu orthodoxe ?

              • Partager sur Facebook
              • Partager sur Twitter
              Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                30 août 2014 à 16:23:04

                Pour avoir un tableau de boutons.

                Du coup je peux boucler pour le chargement d'image, je peux boucler pour l'affichage. Si j'ai une variable pour chaque image, c'est un peu lourd.

                Et puis bonjour l'affichage :

                target.draw(bouton1);
                target.draw(bouton2);
                target.draw(bouton3);
                
                // ...
                
                target.draw(element1);
                target.draw(autreElement);



                -
                Edité par Maluna34 30 août 2014 à 16:24:06

                • Partager sur Facebook
                • Partager sur Twitter
                  30 août 2014 à 17:43:22

                  Tu veux pas boucler sur un conteneur, plutot ?

                  • Partager sur Facebook
                  • Partager sur Twitter
                    30 août 2014 à 18:41:34

                    Je pense que tu utilises la SFML donc ce code devrai te convenir pour créer une liste d'objets que tu peux afficher (non testé)

                    // Stockage des objets
                    std::vector<std::shared_ptr<sf::Drawable>> obj_;
                    
                    // Ajout d'objets
                    obj_.push_back(std::make_shared<sf::Sprite>(/*args*/))
                    //...
                    
                    // Affichage
                    for(auto i:obj_)
                    {
                        target.draw(*i);
                    }
                    • Partager sur Facebook
                    • Partager sur Twitter
                      30 août 2014 à 20:00:21

                      michelbillaud a écrit:

                      Tu veux pas boucler sur un conteneur, plutot ?

                      Ben si, c'est ce que je fais ! :D Le tout est stocké dans un std::vector, et j'utilise une énumération pour ordonner mes objets et accéder aux éléments voulus lorsque je dois appliquer une action spécifique. Mais c'est aussi ce qui a été critiqué ici.

                      Deomys a écrit:

                      Je pense que tu utilises la SFML donc ce code devrai te convenir pour créer une liste d'objets que tu peux afficher (non testé)

                      // Stockage des objets
                      std::vector<std::shared_ptr<sf::Drawable>> obj_;
                      
                      // Ajout d'objets
                      obj_.push_back(std::make_shared<sf::Sprite>(/*args*/))
                      //...
                      
                      // Affichage
                      for(auto i:obj_)
                      {
                          target.draw(*i);
                      }

                      De même déjà fait, je répondais juste à bacelar.

                      • Partager sur Facebook
                      • Partager sur Twitter
                        30 août 2014 à 20:07:03

                        Dans ce cas utilise une std::map avec des std::string en clés pour identifier tes éléments.

                        Et tu y accedes comme ça:

                        obj_["BUTTON_1"]->setPosition(x, y);
                        

                        Et pour afficher tu boules dessus.

                        • Partager sur Facebook
                        • Partager sur Twitter
                          30 août 2014 à 20:32:13

                          Maluna34 a écrit:

                          michelbillaud a écrit:

                          Tu veux pas boucler sur un conteneur, plutot ?

                          Ben si, c'est ce que je fais ! :D Le tout est stocké dans un std::vector, et j'utilise une énumération pour ordonner mes objets et accéder aux éléments voulus lorsque je dois appliquer une action spécifique. Mais c'est aussi ce qui a été critiqué ici.

                          Tu peux avoir fromage et dessert : des variables et un (ou des) conteneurs quand il s'agit de faire des trucs en bloc

                          #include <iostream>
                          #include <memory>
                          #include <vector>
                          
                          using namespace std;
                          
                          class  Personnage {
                            private:
                              string m_n;
                            public:
                            Personnage(const string & n) 
                              : m_n(n)
                            {}
                            void draw() const {
                              cout << "Drawing " << m_n << endl;
                            }
                          };
                          
                          int main(int argc, char **argv)
                          {
                          	auto laurel = make_shared<Personnage>("stanley laurel");
                            auto hardy  = make_shared<Personnage>("oliver hardy");
                            
                            vector<shared_ptr<Personnage>> comiques;
                            comiques.push_back(laurel);
                            comiques.push_back(hardy);
                            
                            // action sur conteneur
                            for(auto p : comiques) {
                              p->draw();
                            }
                            
                            // action spécifique
                            laurel->draw();
                          	return EXIT_SUCCESS;
                          }
                          


                          -
                          Edité par michelbillaud 31 août 2014 à 7:50:27

                          • Partager sur Facebook
                          • Partager sur Twitter
                            30 août 2014 à 22:57:26

                            Honnêtement, je ne vois pas en quoi les énumérations sont un problème. Pour reprendre ce que disait koala01 :

                            koala01 a écrit:

                            Qui dit énumération dit, forcément, test (sans doute à choix multiple)

                            Ben non. Quand je veux accéder à un objet, j'utilise la valeur correspondante, comme je le ferais avec plusieurs variables :

                            // Je veux le bouton 'OK'
                            boutons[OK].f();
                            
                            // Je veux le bouton 'RETOUR'
                            boutons[RETOUR].f();

                            De même que je le ferai avec plusieurs variables :

                            // Je veux le bouton 'OK'
                            boutonOK.f();
                            
                            // Je veux le bouton 'RETOUR'
                            boutonRetour.f();

                            En quoi l'utilisation de tableaux va me faire rajouter des tests ? Mes énumérations ne sont pas faites pour être des valeurs testées, simplement utilisées comme des alias à des indices aux valeurs non significatives.

                            De plus, elles permettent une automatisation non négligeable !

                            for (int i = 0; i < NB_BOUTONS; i++)
                              window.draw(boutons[i]);

                            Je veux rajouter un bouton, en plus d'ajouter l'image dans les ressources du projet, je mets juste sa valeur dans l'énum. Et hop, NB_BOUTONS est mis à jour l'image est chargée toute seule, affichée toute seule. J'ai simplement à définir les caractéristiques spécifiques à cet objet, comme je le ferai avec une variable en fait.

                            -
                            Edité par Maluna34 30 août 2014 à 22:59:33

                            • Partager sur Facebook
                            • Partager sur Twitter
                              31 août 2014 à 23:12:06

                              Salut.

                              @VDD: J'utilise souvent cette méthode sauf que je m'y prend avec un std::map. C'est "fait pour ça" je dirais, pas les vectors. Perso j'pense pas que cette méthode soit mal, c'est super pratique.

                              // enum class si pas dans une classe
                              enum Identif { Truc, Chose, AutreTruk, End };
                              
                              // déclaration de la map
                              std::map< Identif,int > conteneur;
                              
                              // modif de la map
                              conteneur[Truc] = 5;
                              std::cout<<conteneur[Truc];
                              
                              // Parcourir
                              for(int i{}; i < Identif::End; i++)
                                 conteneur[(Identif)i] = 9999;
                              

                              Pas sûr que le cast soit propre par contre.

                              -
                              Edité par Saïcy 31 août 2014 à 23:14:16

                              • Partager sur Facebook
                              • Partager sur Twitter
                                1 septembre 2014 à 7:52:40

                                1)  Si tes clés sont - comme c'est le cas ici -, une suite d'entiers qui part de 0, c'est idiot d'utiliser une map, où l'accès à un élément se fait en temps logarithmique, et non en temps constant.

                                Le problème c'est pas que le logarithme soit grand, c'est qu'il s'y ajoute des constantes qui pénalisent pas mal, par rapport à un tableau, un vecteur, un array. Il s'agit quand même, à chaque accès, de descendre dans un arbre binaire pour chercher la clé.

                                2) Un array est plus approprié. Nous sommes en 2011+n, avec n>0

                                // déclaration 
                                array<int, End > conteneur;
                                 
                                // modif 
                                
                                conteneur[Truc] = 5;
                                std::cout<<conteneur[Truc];
                                 
                                // Parcourir
                                for(auto & element : conteneur)
                                   element = 9999;
                                	



                                -
                                Edité par michelbillaud 1 septembre 2014 à 7:53:32

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  1 septembre 2014 à 11:36:14

                                  @Saïcy

                                  Il semblerait selon mon vdd que les maps ne soient pas la meilleure solution. Mais pour ton parcours, plutôt que le cast hésitant, on peut utiliser des itérateurs. ^^

                                  @michelbillaud

                                  Grosse différence entre les std::vector et les tableaux/std::array ? L'un la taille est fixée, l'autre non. Mais niveau perf ensuite des différences ?

                                  Sinon pour mon soucis, vu que ma première enum n'est pas typée, possible de faire un truc du style :

                                  enum Cliquable_t { BOUTON1, BOUTON2, NB_BOUTONS, CLIQUABLE3 = NB_BOUTONS, CLIQUABLE4, NB_CLIQUABLES };

                                  ? Ainsi, je n'ai pas la liste des boutons en double, ma 1e enum est "comprise" dans la seconde.

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    1 septembre 2014 à 12:11:15

                                    Je ne pense pas que le différence de performance entre array et vector, ou tableau, soit critique dans ce cas.

                                    Après, je vois pas bien quel est ton problème, finalement. parce que "inclure une énumération dans une autre par peur d'en oublier", ça parait assez flou.

                                    Est-ce qu'il s'agit de parcourir des parties d'une énumération ?

                                    enum Comestible { Pomme, Poire, Orange, Navet, Patate, Carotte};
                                    

                                    Dans ce cas on peut s'en tirer facilement

                                    enum Comestible { 
                                      Pomme,   PremierFruit = Pomme,
                                      Poire, 
                                      Orange,  DernierFruit=Orange,
                                      Navet,   PremierLegume = Navet,
                                      Patate, 
                                      Carotte, DernierLegume=Carotte
                                    };
                                    



                                    -
                                    Edité par michelbillaud 1 septembre 2014 à 12:11:56

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      1 septembre 2014 à 12:25:36

                                      Merci beaucoup pour l'exemple, c'est parfait ! :)

                                      Le problème c'est qu'avec les 2 enum, qui listent les même éléments, j'ai de la redondance et une possibilité d'incohérences. Je cherchais donc un moyen d'expliciter "l'ensemble des boutons sont cliquables".

                                      Ton exemple répond à ma question : tu listes une seule fois les éléments et indique les limites Fruits/Légumes, et ils sont tous comestibles. ;)

                                      Pour les énumérations en C/C++, même si celles-ci sont typées, les valeurs attribuées sont toujours des entiers, c'est ça ? (0, 1, 2 ... par défaut ?)

                                      -
                                      Edité par Maluna34 1 septembre 2014 à 12:27:46

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        1 septembre 2014 à 13:06:14

                                        michelbillaud a écrit:

                                        Je ne pense pas que le différence de performance entre array et vector, ou tableau, soit critique dans ce cas.

                                        A priori, il n'y a aucune différence de performance entre array et vector, vu que l'accès se fait en temps constant quoi qu'il arrive...

                                        Le gros avantage de std::array est que le tableau est de taille fixe, définie à la compilation, ce qui nous permet des vérifications à la compilation que std::vector ne nous permet pas.

                                        par exemple, on peut envisager un code proche de

                                        enum MyEnum{
                                           val1,
                                           val2,
                                           /* ... */
                                           valN,
                                           MYENUM_MAX
                                        };
                                        void foo(){
                                           std::array<int, MYENUM_MAX> tab={1,2,3,/*...*/,N};
                                           static_assert(std::extent<decltype(tab)>::value>==MYENUM_MAX,
                                                         "you don't provide the right number of values");
                                        }

                                        Dans certains cas, ca peut être particulièrement intéressant ;)

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                        Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
                                          1 septembre 2014 à 13:17:25

                                          Maluna34 a écrit:

                                          Honnêtement, je ne vois pas en quoi les énumérations sont un problème. Pour reprendre ce que disait koala01 :

                                          Ben non. Quand je veux accéder à un objet, j'utilise la valeur correspondante, comme je le ferais avec plusieurs variables :

                                          // Je veux le bouton 'OK'
                                          boutons[OK].f();
                                          
                                          // Je veux le bouton 'RETOUR'
                                          boutons[RETOUR].f();

                                          De même que je le ferai avec plusieurs variables :

                                          // Je veux le bouton 'OK'
                                          boutonOK.f();
                                          
                                          // Je veux le bouton 'RETOUR'
                                          boutonRetour.f();

                                          En quoi l'utilisation de tableaux va me faire rajouter des tests ? Mes énumérations ne sont pas faites pour être des valeurs testées, simplement utilisées comme des alias à des indices aux valeurs non significatives.

                                          De plus, elles permettent une automatisation non négligeable !

                                          for (int i = 0; i < NB_BOUTONS; i++)
                                            window.draw(boutons[i]);

                                          Je veux rajouter un bouton, en plus d'ajouter l'image dans les ressources du projet, je mets juste sa valeur dans l'énum. Et hop, NB_BOUTONS est mis à jour l'image est chargée toute seule, affichée toute seule. J'ai simplement à définir les caractéristiques spécifiques à cet objet, comme je le ferai avec une variable en fait.

                                          -
                                          Edité par Maluna34 le 30 août 2014 à 22:59:33


                                          A vrai dire je ne suis absolument pas persuadé que tu aies réellement intérêt à travailler de la sorte, et je vois plusieurs raisons à mes doutes :

                                          D'abord, parce que le nombre d'éléments (traçables) contenus par ta fenêtre va rapidement augmenter et que tu ne vas surement pas te contenter de boutons ou d'élément "cliquables" (de manière générale).

                                          Tu vas donc très rapidement te retrouver avec une énumération dans laquelle une chatte ne retrouverait pas ses jeunes, vu que tu devrais rajouter à ton énumération une valeur énumérée correspondant à chacun des éléments visuels de ton IHM.

                                          Ensuite, si tu es au niveau de la fenêtre, et que tu veux en tracer le contenu, tu n'as simplement pas besoin de ton énumération : tu dois faire tracer tous les élément que la fenêtre contient et basta ... A charge de chaque élément de savoir si l'affichage doit effectivement modifier ce qui est vu ou non.

                                          Enfin, c'est la fenêtre qui va provoquer l'émission d'un "événement" correspondant, par exemple au clique, en envoyant la position à laquelle il a eu lieu.  Cet événement sera -- quoi qu'il arrive -- transmis sous la forme d'un "signal" à l'élément qui se trouve à la position en question et, encore une fois, il appartient à l'élément qui reçoit le signal de savoir comment il doit y réagir ;-)

                                          Bref, je crois sincèrement que tu te fais beaucoup de mal pour rien à essayer d'utiliser une énumération pour ce que tu veux faire

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                          Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
                                            1 septembre 2014 à 15:27:45

                                            michelbillaud a écrit:

                                            1)  Si tes clés sont - comme c'est le cas ici -, une suite d'entiers qui part de 0, c'est idiot d'utiliser une map, où l'accès à un élément se fait en temps logarithmique, et non en temps constant.

                                            Le problème c'est pas que le logarithme soit grand, c'est qu'il s'y ajoute des constantes qui pénalisent pas mal, par rapport à un tableau, un vecteur, un array. Il s'agit quand même, à chaque accès, de descendre dans un arbre binaire pour chercher la clé.

                                            2) Un array est plus approprié. Nous sommes en 2011+n, avec n>0

                                            // déclaration 
                                            array<int, End > conteneur;
                                             
                                            // modif 
                                            
                                            conteneur[Truc] = 5;
                                            std::cout<<conteneur[Truc];
                                             
                                            // Parcourir
                                            for(auto & element : conteneur)
                                               element = 9999;
                                            	

                                            -
                                            Edité par michelbillaud il y a environ 7 heures


                                            Ce n'est pas idiot. C'est même très réfléchit: Quand on veut accéder à un élément selon une clé dans un conteneur, comme veut le faire l'OP, on prend une map, car c'est fait pour.

                                            -
                                            Edité par Saïcy 1 septembre 2014 à 15:28:57

                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              1 septembre 2014 à 15:48:01

                                              Saïcy a écrit:

                                              michelbillaud a écrit:

                                              Ce n'est pas idiot. C'est même très réfléchit: Quand on veut accéder à un élément selon une clé dans un conteneur, comme veut le faire l'OP, on prend une map, car c'est fait pour.

                                              -
                                              Edité par Saïcy il y a 8 minutes


                                              Humm... cela mérite néanmoins un très sérieux bémol...

                                              Conceptuellement parlant, tu as tout à fait raison : si tu veux retrouver une valeur à partir d'une clé et que tu as un nombre indéterminé de couples clé / valeur, tu as tout à fat raison : la classe idéale pour ce faire est la std::map.

                                              Par contre, si tu as un nombre clairement déterminé de couples clé / valeur et que, en plus, la clé peut de toutes évidences être considérée comme un index, il devient tout à fait possible "court-circuiter" la taxe à payer du fait de la réallocation d'un tableau lors de l'insertion en veillant à ce que le tableau soit directement à la bonne taille.

                                              Si tu en restes à un tableau "de taille raisonnable" (il ne faut pas essayer avec 1700 lignes de 1700 colonnes sur 1700 plans, aucun système n'aura assez de mémoire :-P ) tu peux alors profiter d'un accès en temps constant au lieu d'un accès en temps logarithmique, ce qui est malgré tout préférable d'un stricte point de vue des performances.

                                              Le tout, sans même parler des risques liés au cache-miss auquel on peut être confronté avec toute collection d'objets autre que le tableau ;-)

                                              Et comme toutes les conditions sont réunies ici (utilisation d'une énumération qui détermine très clairement le nombre d'élément, utilisation des valeurs énumérées comme indice possible et nombre d'éléments malgré tout "raisonnable"), tu aurais sans doute tord de te priver de l'utilisation d'un tableau ;-)

                                              -
                                              Edité par koala01 1 septembre 2014 à 15:50:11

                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                              Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait

                                              Inclure une énumération dans une autre

                                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                              • Editeur
                                              • Markdown