Partage
  • Partager sur Facebook
  • Partager sur Twitter

Itérateur pour conteneur personnalisé

Implémentation compatible avec la STL

Sujet résolu
    2 janvier 2009 à 21:28:56

    Bonsoir.

    Je cherche en ce moment à créer une classe conteneur qui ressemble aux conteneurs de la STL mais je bute sur les itérateurs :

    Citation : www.cplusplus.com

    For example, each container type (such as a vector) has a specific iterator type designed to iterate through its elements in an efficient way.


    Je veux bien être d'accord, mais comment est-ce que je dois définir mon itérateur particulier pour qu'il fonctionne avec d'autres fonctions de la STL comme sort() ? J'ai du mal à comprendre ce qui se cache derrière la syntaxe des itérateurs de la STL, par exemple dans vector<int>::iterator it ;
    je ne comprends pas ce que traduit l'opérateur de résolution de portée.

    Et je n'arrive pas à trouver non plus quelles fonctions/opérateurs il faut définir pour qu'il soit utilisable par d'autres fonctions de la STL...

    Si quelqu'un pouvait me donner un petit coup de pouce ou me diriger vers de la documentation sur le sujet ce ne serait pas de refus ^^
    • Partager sur Facebook
    • Partager sur Twitter
      2 janvier 2009 à 21:53:53

      la classe vector est une classe générique! Donc déclarer un vector n'a pas de sens! Tu déclares un vector d'entiers, de float, etc... Donc, il faut obligatoirement utiliser :

      vector<int>::
      • Partager sur Facebook
      • Partager sur Twitter
        2 janvier 2009 à 22:12:42

        Je crois qu'il voulait parler du "iterator"...
        Eh bien, c'est une classe interne à vector...
        En fait, vector pourrait ressembler à:
        namespace std
        {
            template<class T>
            class vector
            {
                // ...
            public:
                class iterator
                {
                    // ...
                };
                // ...
            };
        }
        
        • Partager sur Facebook
        • Partager sur Twitter
          2 janvier 2009 à 22:17:36

          Il a aussi parlé de l'opérateur de résolution de portée! ;)
          • Partager sur Facebook
          • Partager sur Twitter
            2 janvier 2009 à 22:27:57

            vector<int>::iterator est une classe définie à l'intérieur de la classe vector comme le montre Ice_Keese dans son code. Ceci explique l'utilisation de l'opérateur de résolution de portée "::" .

            Sinon, Lord of Mushrooms commence par lire ca, ca pourrait t'éclairer : http://cpp.developpez.com/cours/cpp/?page=page_16#LXVI-D
            • Partager sur Facebook
            • Partager sur Twitter
            Inkamath on GitHub - Interpréteur d'expressions mathématiques. Reprise du développement en cours.
              2 janvier 2009 à 22:41:41

              Citation : Debian

              Il a aussi parlé de l'opérateur de résolution de portée! ;)


              Je suis un programmeur du dimanche, il est donc possible que j'ai appelé une chose avec le nom d'une autre : l'opérateur de résolution de portée, ce n'est pas "::" ? Comme je l'ai compris, vector<int> n'est ici qu'un opérande non ?

              Citation : Ice_Keese

              Je crois qu'il voulait parler du "iterator"...


              Exactement ! Merci beaucoup Ice_Keese ;)

              J'ai jetté un rapide coup d'oeil au lien que tu m'as donné iNaKoll et il semblerait que ce soit ce que je cherche, je vais aller voir ça de plus près ^^
              • Partager sur Facebook
              • Partager sur Twitter
                2 janvier 2009 à 22:53:50

                std::vector<T>::iterator est une classe imbriquée de std::vector<T> (enfait c'est sûrement un typedef d'une classe imbriquée au nom incompréensible, mais ça osef). Sinon voici mes liens de références (j'en ai sûrement oublié):
                http://www2.roguewave.com/support/docs [...] terators.html
                http://www2.roguewave.com/support/docs [...] r-traits.html
                http://www2.roguewave.com/support/docs [...] iterator.html

                Tu trouveras des infos dans les 2 derniers liens de ma signature.
                • Partager sur Facebook
                • Partager sur Twitter
                  3 janvier 2009 à 14:00:42

                  En partant du même lien que iNakoll, regarde aussi la notion d'allocateur (notion utilisé par tout les conteneurs), et la section 17 sur les conteneurs (tu pourras savoir quels fonctions définir, section 18 sur les algo peut aider aussi).
                  • Partager sur Facebook
                  • Partager sur Twitter
                  FaQ : Fr | En 1 2 | C++11 | Template || Blog : Deloget | C++|Boost--Dev | C++Next | GotW || Installer Boost
                    3 janvier 2009 à 16:41:59

                    Une façon de faire: http://hermitte.free.fr/Info/C++/libs/luc_lib/circular_list.hpp (la doc est probablement à l'ouest)
                    (le .cpp de test associé par là: http://hermitte.free.fr/Info/C++/tests/circular_list.cpp)

                    Et il y a des classes utilitaires dans boost pour simplifier la définition d'itérateurs.
                    • Partager sur Facebook
                    • Partager sur Twitter
                    C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
                      4 janvier 2009 à 2:10:29

                      Eh bien ça fait de la lecture tout ça ! ! :lol: Merci à tous ! J'ai commencé à coder ma classe iterator mais je fais face à quelques problèmes.

                      Le premier concerne les opérateurs suffixés ++ et -- : comment incrémenter l'itérateur seulement après l'avoir renvoyé ? J'ai pensé à quelque chose du genre :

                      const iterator& iterator::operator++() {
                          const iterator itTemp(*this) ;
                          // ... je fais pointer mon itérateur sur l'élement suivant ...
                          return itTemp ;
                      }
                      

                      Mais je ne suis pas sûr que copier l'itérateur à chaque fois soit une bonne idée...

                      Mon second problème concerne ces mêmes opérateurs, mais préfixés cette fois ! Puisqu'on les utilise de cette manière ++it, il y a un opérande à droite, on aurait donc le prototype :

                      iterator& iterator::operator++(iterator& p_it)
                      

                      Mais alors comment éviter qu'on mette un opérande à gauche ? Je veux dire avec ce prototype il serait possible d'écrire it_1 ++ it_2 sans qu'il y ait d'erreur, non ?
                      • Partager sur Facebook
                      • Partager sur Twitter
                        4 janvier 2009 à 3:19:21

                        Iterator &operator++(void)
                        {
                            // inc
                            return *this;
                        }
                        
                        Iterator operator++(int)
                        {
                            Iterator Tmp(*this);
                            // ++(*this);
                            return Tmp;
                        }
                        
                        • Partager sur Facebook
                        • Partager sur Twitter
                          4 janvier 2009 à 3:25:52

                          Bonsoir,

                          Les opérateurs suffixés et postfixés d'incrémentation et de décrémentation sont unaire. Autrement dit, ils ne prennent qu'un seul opérande et il se trouve qu'il est passé implicitement en paramètre : c'est this. Ainsi aucun de ces opérateurs ne prend réellement de paramètre.

                          Afin de différencier les opérateurs préfixés/suffixés qui ont à priori la même signature, en C++ on fait comme ceci :

                          iterator& iterator::operator++(void); // opérateur préfixé
                          iterator  iterator::operator++(int); // opérateur suffixé
                          


                          En ce qui concerne l'opérateur suffixé on l'implémente généralement comme ceci :
                          iterator  iterator::operator++(int)
                          {
                              iterator tmp(*this);
                              ++(*this);
                              return tmp;
                          }
                          


                          PS : Bon, je suis à moitié grillé par Chlab_lak, j'espère que mes explications serviront quand même un peu ^^
                          • Partager sur Facebook
                          • Partager sur Twitter
                          Inkamath on GitHub - Interpréteur d'expressions mathématiques. Reprise du développement en cours.
                            4 janvier 2009 à 11:15:07

                            J'ai peut-être une légère préférence pour la version avec explications, mais rien de bien méchant ^^ Merci à tous les deux pour vos réponses ! !
                            • Partager sur Facebook
                            • Partager sur Twitter
                              4 janvier 2009 à 13:32:15

                              Objet constant pour le post, cf ici (ou d'autre cour sur les opérateurs).
                              • Partager sur Facebook
                              • Partager sur Twitter
                              FaQ : Fr | En 1 2 | C++11 | Template || Blog : Deloget | C++|Boost--Dev | C++Next | GotW || Installer Boost

                              Itérateur pour conteneur personnalisé

                              × 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