Partage
  • Partager sur Facebook
  • Partager sur Twitter

Petit problème avec std::vector.

Sujet résolu
    28 juillet 2021 à 20:58:50

    Bonjour, il me semble que lorsque l'on déclarer une variable statique elle n'est pas détruite à la fin de l'exécution du bloc de code dans laquelle on l'a déclarée.

    Par exemple ce code compte le nombre de type créer :

    template <typename T>
    struct UniqueTypeId {
        static size_t typeId;
    };
    template <typename T>
    size_t UniqueTypeId<T>::typeId = next();

     Par contre ce n'est pas le cas pour les std::vector on dirait :

    template <typename T>
    static void addComponent(T component) {
        static std::vector<T> components;
        components.push_back(component);
    }
    template <typename T>
    static size_t getNbComponents() {
        static std::vector<T> components;
        std::cout<<"vector size : "<<components.size()<<std::endl;
        return components.size();
    }
    int main(int argc, char* argv[]){
        int i = 0, j = 1;
        addComponent(i);
        addComponent(j);
        std::cout<<"nb components : "<<getNbComponents<int>()<<std::endl;
        return 0;
    } 
    

    Ce code ici la taille du std::vector est toujours zéro même si j'ajoute des éléments dans le std::vector, pourquoi ?

    Ah oui c'est parce que je le déclare dans deux fonctions différentes !!!

    -
    Edité par OmbreNoire 28 juillet 2021 à 21:07:56

    • Partager sur Facebook
    • Partager sur Twitter
      28 juillet 2021 à 21:30:14

      >lorsque l'on déclarer une variable statique

      Lors de mon dernier référencement (qui date en décennie), il y avait 6 types de variables statiques.

      Alors, encore une fois, @OmbreNoire, un peu de rigueur/détail dans vos questions et surtout dans vos assertions, MERCI !!!

      >elle n'est pas détruite à la fin de l'exécution du bloc de code dans laquelle on l'a déclarée.

      Oui, dans la très grande majorité de leurs usages (tout type de variable statiques confondues).

      Ouais, des templates statiques, on va pas trop chercher le dahu.

      Quelle opération magique doit faire votre compilateur pour savoir que la variable locale (même si elle statique) "components" de la fonction "addComponent" doit être la même que la variable locale "components" de la fonction "getNbComponents" ?

      P.S.: Franchement comparer un champ statique d'une structure et une variable statique de fonction dans un template statique, c'est vraiment comparer une baleine bleue à une banane.

      • Partager sur Facebook
      • Partager sur Twitter
      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
        29 juillet 2021 à 0:31:26

        Salut,

        Il faut juste faire attention que, ici, tu as deux variables statiques, qui appartiennent à  des fonctions différentes, mais qui portent le même nom...

        En fonction de la fonction que tu vas appeler, tu  te retrouvera donc soit à manipuler le vecteur qui est déclaré dans addComponent, et qui, lui, va augmenter (étant donné qu'on fait un push_back dessus) soit le vecteur qui est déclaré dans getNbComponents et qui, lui, ne sera jamais modifié (vu qu'on ne le tient que par  le tout petit bout de la laisse à savoir sa fonction size).

        Si tu veux que les deux fonctions manipulent un seul et même vecteur, tu dois passer par une fonction commune (par exemple getComponentContainer) qui renverrait une référence sur la (seule et unique) variable statique du lot.  Cela donnerait quelque chose comme

        template< typename T>
        
        std::vector<T> & getComponentContainer{
            static std::vector<T> container; // le seul vecteur static du lot
            return container;
        }
        template <typename T>
        void addComponent( T component){
            auto & container = getComponentConainer<T>();
            container.push_back(component);
            /* on peut rendre les choses plus concises avec
            getComponentContainer<T>().push_back(compoent);
            */
        }
        template <typename T>
        size_t getNbComponents(){
            auto & container = getComponentConainer<T>();
            return container.size();
            /* on peut rendre les choses plus concises avec
            return getComponentContainer<T>().size();
            */
        }



        • 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 juillet 2021 à 3:18:33

          koala01 a écrit:

          Salut,

          Il faut juste faire attention que, ici, tu as deux variables statiques, qui appartiennent à  des fonctions différentes, mais qui portent le même nom...

          En fonction de la fonction que tu vas appeler, tu  te retrouvera donc soit à manipuler le vecteur qui est déclaré dans addComponent, et qui, lui, va augmenter (étant donné qu'on fait un push_back dessus) soit le vecteur qui est déclaré dans getNbComponents et qui, lui, ne sera jamais modifié (vu qu'on ne le tient que par  le tout petit bout de la laisse à savoir sa fonction size).

          Si tu veux que les deux fonctions manipulent un seul et même vecteur, tu dois passer par une fonction commune (par exemple getComponentContainer) qui renverrait une référence sur la (seule et unique) variable statique du lot.  Cela donnerait quelque chose comme

          template< typename T>
          
          std::vector<T> & getComponentContainer{
              static std::vector<T> container; // le seul vecteur static du lot
              return container;
          }
          template <typename T>
          void addComponent( T component){
              auto & container = getComponentConainer<T>();
              container.push_back(component);
              /* on peut rendre les choses plus concises avec
              getComponentContainer<T>().push_back(compoent);
              */
          }
          template <typename T>
          size_t getNbComponents(){
              auto & container = getComponentConainer<T>();
              return container.size();
              /* on peut rendre les choses plus concises avec
              return getComponentContainer<T>().size();
              */
          }

          Ah c'est ce que je voulais faire, merci!!! (Résolu)
          • Partager sur Facebook
          • Partager sur Twitter
            29 juillet 2021 à 7:18:12

            OmbreNoire a écrit:

            Ah oui c'est parce que je le déclare dans deux fonctions différentes !!!

            Nous dit le type qui programme en C++ depuis 10 ans...

            Principes de base (valables depuis C)

            • un truc déclaré dans un bloc n'est visible que depuis ce bloc (idem pour fonction)
            • une variable déclarée static est rémanente.

            -
            Edité par michelbillaud 29 juillet 2021 à 7:20:23

            • Partager sur Facebook
            • Partager sur Twitter

            Petit problème avec std::vector.

            × 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