Partage
  • Partager sur Facebook
  • Partager sur Twitter

Tableau passé en Paramètres d'un vecteur

Adresses du tableau passées

    14 août 2018 à 14:18:21

    Bonjour, 

    Dans le cadre d'un de mes cours, je me retrouve confronté à une syntaxe que je ne comprends pas. 

    Dans le programme, un tableau est déclaré et ensuite un vecteur avec deux paramètres.

    Ces deux paramètres doivent, si j'ai bien compris, contenir la taille et les éléments qui s'y trouveront.

    Par ex vector <int> V (5,7) est un tableau de longueur 5, contenant 7 dans chaque case. 

    Ici, dans le programme sont passées en paramètres les adresses du tableau et du tableau + 7. Voici le code, ce que je comprends pas concerne V1.

    #include <iostream>
    #include <string>
    #include <vector>
    #include <list>
    #include <algorithm>
    using namespace std;
    void Affiche_V(vector<int> V, string S) {
    	cout << S << " : ";
    	for (int i = 0; i< V.size(); i++) {
    		cout << V[i] << " ";
    	}
    	cout << endl;
    }
    void Affiche_L(list<int>::iterator it, list<int> Liste, string S) {
    	cout << S << " : ";
    	for (it = Liste.begin(); it != Liste.end(); it++) {
    		cout << *it << " ";
    	}
    	cout << endl;
    }
    int main() {
    	int T1[7] = { 3, 5, 9, 1, 4, 18, 5 };
    	int T2[5] = { 9, 1, 7, 2, 5 };
    	int TT[15] = { 0 };
    	vector<int> V1(T1, T1 + 7), V2(T2, T2 + 5), VV(TT, TT + 15);
    	Affiche_V(V1, "Vect1 Initial");
    	Affiche_V(V2, "Vect2 Initial");
    	Affiche_V(VV, " VV Initial");

    Je ne comprends pas la ligne avec vector<int> V1(T1, T1 + 7), qqun peut-il m'éclairer ? 

    Merci !

    -
    Edité par PaxB 14 août 2018 à 14:18:45

    • Partager sur Facebook
    • Partager sur Twitter
      14 août 2018 à 14:33:05

      Il existe un constructeur de vector qui prend deux itérateurs en paramètre. Le constructeur copie tous les éléments dans  [first, last[ ([first, last) en notation anglosaxone) dans le vecteur lors de sa construction.

      Ici, les itérateurs sont des pointeurs vers éléments dans un tableau statique C. Je préfère l'écriture &T1[0] et &T1[7], ou mieux: std::begin(T1), std::end(T1) (C++ 11). Quand on passe le nom d'un tableau à quelque chose qui attend un pointeur, il y a une dégénérescence (decay en VO) implicite du tableau en pointeur -- héritage du C. C'est ce qu'il se passe ici. Il y a beaucoup de choses qui se mélangent dans l'extrait de code qui te chagrine.

      -
      Edité par lmghs 14 août 2018 à 14:33:32

      • 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.
        14 août 2018 à 16:33:26

        Accessoirement, cette syntaxe est inutile maintenant :

        std::vector<int> V1 = { 3, 5, 9, 1, 4, 18, 5 };
        std::vector<int> V2 = { 9, 1, 7, 2, 5 };
        std::vector<int> V3(15);

        Voire mieux :

        std::array<int, 7> V1 = { 3, 5, 9, 1, 4, 18, 5 };
        std::array<int, 5> V2 = { 9, 1, 7, 2, 5 };
        std::array<int, 15> V3 = {}; // j'ai un doute...

        Et sinon, on signale la violence de passer les vector par copie ?

        Et pour l'affichage, préférer les range-based loops:

        for (int i: v) {
            cout << i << " ";
        }

        (Changes de cours, de prof, d'école...)

        • Partager sur Facebook
        • Partager sur Twitter
          14 août 2018 à 20:35:13

          `std::array< int, 7> v1 =` est pour moi une régression par rapport à `int v1[] =`, on perd le DRY.

          Et... mais du coup, le C++17 corrige le tir, non? (je n'ai pas encore joué avec l'autodéduction template sur les constructions)

          -
          Edité par lmghs 14 août 2018 à 20:36:19

          • 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.
            14 août 2018 à 21:40:46

            PaxB a écrit:

            [blablabla]


            Bon, déjà, pour poser la question, ça aurait été plus simple de réduire à : "je ne comprends pas ceci".

            int T1[7] = { 3, 5, 9, 1, 4, 18, 5 };
            vector<int> V1(T1, T1 + 7);
            

            Il faut aller voir du côté des constructeurs de vector. "des", parce qu'il y en a plusieurs :


            Là on est dans le cas (3) : les deux paramètres sont des InputIterator

            - T1 est un InputIterator qui démarre sur T1[0]

            - T1 + 7 démarre sur T1[7]

            et le constructeur va prendre ce qui part de T1[0] jusqu'à arriver à T1[7], exclus.  Donc ca construit une copie contenant T1[0]...T1[6].

            • Partager sur Facebook
            • Partager sur Twitter
              15 août 2018 à 14:52:26

              @lmghs

              Moi non plus, je n'ai pas trop joué avec. Mais je pense que ca permet de deduire les types, pas les valeurs. Cf https://en.cppreference.com/w/cpp/language/class_template_argument_deduction 

              Donc non, ca resout pas le probleme de DRY.

              Bon, apres, si tu veux etre joueur et eviter le DRY, tu peux ecrire :

              #include <iostream>
              
              void foo(auto const& v) {
                  for (auto const& i: v) 
                      std::cout << i << std::endl;
              }
               
              int main()
              {
                  const auto v1 = { 3, 5, 9, 1, 4, 18, 5 };
                  foo(v1);
              }
              

              ;)

              • Partager sur Facebook
              • Partager sur Twitter
                15 août 2018 à 16:46:13

                @gbdivers. Ici v1 est un initializer_list, plutôt bof aussi. Il faudrait un make_array pour abandonner les tableaux statiques du C.
                • 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.
                  15 août 2018 à 16:55:18

                  On peut faire un constructeur variadique avec les déductions et déduire le nombre d'élément et le type de std::array. Donc si, ça marche et c'est franchement cool :)

                  • Partager sur Facebook
                  • Partager sur Twitter
                    15 août 2018 à 17:13:11

                    https://en.cppreference.com/w/cpp/experimental/make_array 

                    Mais je ne sais plus si c'est dans le C++20 ou pas.

                    D'un autre côté, si on peut ecrire du code generique comme j'ai fait (soit avec des templates, de la deduction de type ou des concepts), est-ce que c'est si bof ?

                    void foo(CollectionConcept const& v) {
                        for (auto const& i: v)
                            std::cout << i << std::endl;
                    }

                    On declare et on se focus que sur ce qui est important. Peut importe le type soujacent. (Surtout que si initializer_list convient, pourquoi se priver ? Et pourquoi ajouter le cout de la creation d'un std::array ?)

                    • Partager sur Facebook
                    • Partager sur Twitter
                      17 août 2018 à 11:30:25

                      Merci ! 

                      Effectivement j'aurais pu réduire la question, mais je voulais exprimer ce que je pensais comprendre :) 

                      • Partager sur Facebook
                      • Partager sur Twitter

                      Tableau passé en Paramètres d'un vecteur

                      × 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