Partage
  • Partager sur Facebook
  • Partager sur Twitter

C++ Scott Meyers, transmission parfaite

C++

    27 octobre 2018 à 17:01:49

    Bonjour OC :)

    d'abord, je cite le passage du livre traduit en français de Scott Meyers , sur lequel j'ai une question, après je mets la question :

    "Il est important de faire a différence entre les arguments et les paramètres, car les paramètres sont des lvalues, alors que les arguments qui servent à les initialiser peut être des ravalues ou  des lvalues" ......... jusque là, tout est ok pour moi. Puis :

    "Cela concerne e particulier le processus de transmission parfaite, au cous duquel un argument passé à une fonction est transmis à une seconde fonction en conservant le statut de rvalue ou lvalue de l'argument d'origine"

    Même si La transmission parfaite est abordée après dans le livre, je souhaite vous demander si vous pouvez me donner un exemple précis de ce qui a été dit dans :

    "Cela concerne e particulier le processus de transmission parfaite, au cous duquel un argument passé à une fonction est transmis à une seconde fonction en conservant le statut de rvalue ou lvalue de l'argument d'origine"


    avec quelques explications pour bien comprendre.

    Merci par avance

    PS : "Programmez efficacement en C++ de Scott Meyers"

    EDIT : deuxième question :

    MichelBllaud m'avait parlé une fois de "fermeture". Ici Scott Meyers dit :

    "Les objets fonctions créés par des expressions lambda sont appelés fermetures".

    Pourriez-vous me donner un exemple précis de cela ?

    Merci aussi

    -
    Edité par pseudo-simple 27 octobre 2018 à 17:17:50

    • Partager sur Facebook
    • Partager sur Twitter
      27 octobre 2018 à 17:26:34

      Pour le premier :

      void f(Object o1) { ... }
      
      void g(Object o2) { f(o2); }
      
      int main() {
          g(lvalue);
          g(rvalue);
      }

      La transmission de parametre, c'est g qui appelle f en lui transmettant des paramètres qu'il a reçu (o2 ici)

      Le "perfect forwarding", c'est quand le type de valeur (lvalue ou rvalue) est respecté. C'est a dire que g appelle f avec une lvalue si g a ete appelé avec une lvalue, et appelle f avec une rvalue si g a ete appelé avec une rvalue.

      Or, comme le dit Meyers : "car les paramètres sont des lvalues", donc dans ce code, o2 est une lvalue, peu importe si g a ete appelé avec une lvalue ou une rvalue. 

      Pour la question 2, ce qu'on appelle une fermeture, c'est en gros la fonction lambda quand elle est un objet.

      auto f = [](){};



      -
      Edité par gbdivers 27 octobre 2018 à 17:56:26

      • Partager sur Facebook
      • Partager sur Twitter
        27 octobre 2018 à 17:38:07

        Bonjour gbdivers

        merci pour tes réponses. Je suppose qu'il manque plusieurs parenthèses dans ton code ? et qu'il manque de choses ? (o10...)

        -
        Edité par pseudo-simple 27 octobre 2018 à 17:40:29

        • Partager sur Facebook
        • Partager sur Twitter
          27 octobre 2018 à 17:41:10

          Oui, j'ai merdouillé un peu avec les parentheses. Fixed.

          -
          Edité par gbdivers 27 octobre 2018 à 17:41:26

          • Partager sur Facebook
          • Partager sur Twitter
            27 octobre 2018 à 17:54:27

            Ne voulais-tu pas dire f(o2) plutôt que f(o1) ?

            -
            Edité par pseudo-simple 27 octobre 2018 à 17:54:43

            • Partager sur Facebook
            • Partager sur Twitter
              27 octobre 2018 à 18:16:28

              Juste pour l'exemple pour ma curiosité, si le principe de perfect forwarding était respecté ici,

              comment écrirais-tu le code de manière le plus simple possible ?

              Merci

              EDIT quand tu dis :

              "Or, comme le dit Meyers : "car les paramètres sont des lvalues", donc dans ce code, o2 est une lvalue, peu importe si g a ete appelé avec une lvalue ou une rvalue. "

              EDIT2 :

              Je reformule mieux ma question : quel mécanisme sera utilisé , à priori, si par exemple une rvalue est transmise en argument, alors qu'en paramètre comme dans ton exemple, une lvalue est attendue ?

              ça va pas passer la compilation ?

              Merci

              -
              Edité par pseudo-simple 27 octobre 2018 à 23:09:35

              • Partager sur Facebook
              • Partager sur Twitter
                27 octobre 2018 à 18:37:24

                C'est expliqué dans le livre : std::forward + forward references.
                • Partager sur Facebook
                • Partager sur Twitter
                  27 octobre 2018 à 19:18:51

                  Pour le EDIT de mon dernier message aussi ?
                  • Partager sur Facebook
                  • Partager sur Twitter
                    27 octobre 2018 à 19:37:27

                    YES, man a écrit:

                    cette valeur sera transformée en lvalue

                    Ca ne veut rien dire. Une valeur ne peut pas etre "transformé". Toutes les expressions ont une "value categorie" ( https://en.cppreference.com/w/cpp/language/value_category ), qui ne change pas.

                    Je ne suis pas sur que tu as compris le problème. Peut tu ecris un code simple qui reproduit le problème de la transmission de valeurs ?

                    • Partager sur Facebook
                    • Partager sur Twitter
                      27 octobre 2018 à 22:48:52

                      J'ai fait un EDIT2 pour reformuler plus précisément ma question afin que tu comprennes.

                      Merci par avance pour ta réponse

                      • Partager sur Facebook
                      • Partager sur Twitter
                        27 octobre 2018 à 23:13:38

                        J'avais compris ta question. Mais la formulation de ta question (et meme apres ton edition) me laisse penser que tu n'as pas compris les categories de valeurs. D'où ma question. Si tu ne sais pas écrire un code qui permet de "voir" la catégorie de valeur, comment peux tu comprendre la transmission et la transmission parfaite.

                        On va faire par étape. 

                        1. Ecrire un code qui permet de "voir" les categories de valeur

                        Complète le code suivant :

                        #include <iostream>
                        
                        // declaration de f
                        void f(...) { ... }
                        
                        int main() {
                            // appel de f avec une lvalue
                            f(...);
                        
                            // appel de f avec une rvalue
                            f(...);
                        }

                        Et il faut que ce code affiche :

                        f a ete appele avec une lvalue
                        f a ete appele avec une rvalue

                        2. La transmission

                        Modifie le code de facon a ce que f soit appellé via une fonction g (sans modifier le code de f, et en remplaçant uniquement f par g dans main)

                        #include <iostream>
                        
                        // declaration de f
                        void f(...) { ... }
                        
                        // declaration de g
                        
                        void g(...) { f(...); } 
                        
                        int main() {
                            // appel de g avec une lvalue
                            g(...);
                        
                            // appel de g avec une rvalue
                            g(...);
                        }

                        Quel est le problème dans ce qui est affiché ?

                        3. Perfect forwarding

                        Corriger le code en utilisant le perfect forwarding de façon a afficher le résultat attendu.

                        -
                        Edité par gbdivers 27 octobre 2018 à 23:13:59

                        • Partager sur Facebook
                        • Partager sur Twitter
                          27 octobre 2018 à 23:13:43

                          Une fermeture, c'est un truc qu'on peut exécuter, qui contient donc du code, comme une fonction, mais qui en général _renferme_ aussi des données.

                          En C++, ces données sont récupérées par la liste de captures.

                          Exemple :

                            int n = 3;
                            
                            auto  fermeture = [n](int e) { 
                              return n + e; 
                            };
                              
                            n = 4;
                            std::cout << fermeture(10) << std::endl;
                            

                          le code ci-dessus affiche 13, parce que la fermeture contient une copie de la valeur de n (3), qui a été _capturée_ au moment de la construction.

                          Maintenant si on avait écrit

                          auto  fermeture = [& n](int e) {    // capture d'une référence
                              return n + e; 
                            };

                          la fermeture contiendrait une _référence_ à la variable n, et se servirait de sa valeur actuelle.



                          -
                          Edité par michelbillaud 27 octobre 2018 à 23:16:04

                          • Partager sur Facebook
                          • Partager sur Twitter
                            27 octobre 2018 à 23:16:33

                            @michelbillaud Ta définition implique que les foncteurs (object-fonction) seraient de capture aussi. On est bien d'accord que c'est un terme qu'on reserve qu'au lambda ?
                            • Partager sur Facebook
                            • Partager sur Twitter
                              27 octobre 2018 à 23:17:42

                              Je n'ai pas donnée une définition, juste une explication.

                              La définition de wikipedia, qui sait tout, c'est

                              << a closure (also lexical closure or function closure) is a technique for implementing lexically scoped name binding in a language with first-class functions. Operationally, a closure is a record storing a function[a] together with an environment. >>

                              Je ne comprends pas ce que tu appelles "être de capture". 

                              Il me semble que les foncteurs (des objets qui ont une surcharge de operator() ) permettent aussi de bidouiller une capture (lier des variables internes - qui serviront plus tard - à des éléments de l'environnement)  en bataillant avec le constructeur, dans le C++ pré 11, qui n'avait pas de fonctions "de première classe".

                              Mais bon, on bricoler des clotures en C aussi, pas de problème. Une structure qui contient les adresses et les données capturées, et un pointeur sur la fonction qu'il faudra appeler. On se débrouille avec. C'est juste que c'est pas des éléments du langage.

                              -
                              Edité par michelbillaud 27 octobre 2018 à 23:38:39

                              • Partager sur Facebook
                              • Partager sur Twitter
                                28 octobre 2018 à 1:20:10

                                @gbdivers, merci pour ton exercice en 3 étapes. je réfléchis

                                Si je comprends pour la première étape, je dois trouver un moyen (je pense à un if) où en gros, je dis : "si le paramètre est une lvalue, fais ceci, sinon fais cela ?"

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  28 octobre 2018 à 2:46:12

                                  @Yes, man : oui, c'est ce que tu dois obtenir. Reponds juste a la question 1, on verras les autres questions quand la premiere sera resolue.

                                  Tu peux meme donner que le code de la fonction main de la question 1 pour commencer, on verra le reste du code pour la fonction f aprés.

                                  @ michelbillaud : mal exprimé. Je demandais juste si tu classais les foncteurs comme etant des fermetures. (Perso, je reserve le terme "closure" pour les lambdas)

                                  -
                                  Edité par gbdivers 28 octobre 2018 à 2:48:03

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    28 octobre 2018 à 5:12:00

                                    Y'a t-il un moyen générique de caractériser une lvalue ou une ravlue ?

                                    ou bien par exemple dans le cas d'une rvalue, je dois distinguer les sous-cas de savoir si c'est un retour de fonction, une valeur explicite...

                                    Merci

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      28 octobre 2018 à 11:36:49

                                      gbdivers a écrit:

                                      @ michelbillaud : mal exprimé. Je demandais juste si tu classais les foncteurs comme etant des fermetures. (Perso, je reserve le terme "closure" pour les lambdas)

                                      Bon, déjà, faut remarquer que Stroustrup a employé de travers le terme "foncteur",  pour désigner pompeusement  des objets C++ qu'on peut appeler comme des fonctions, avec un coup de surcharge de operator(). 

                                      Mal nommer les choses, ç'est ajouter au malheur du monde, comme le disait Camus, et  bien avant lui Confucius (551-479 av JC) «Si j’étais chargé de gouverner, je commencerais par rétablir le sens des mots».

                                      En principe, les foncteurs,  c'est la généralisation des morphismes aux catégories (en maths) - en gros, une fonction qui à une fonction associe une fonction -  et dans la tradition de la programmation fonctionnelle, dans un sens très voisin, c'est un machin qui combine des fonctions pour en fabriquer d'autres.

                                      Par exemple si on avait défini, sur les entiers, des fonctions  estPair et estPositif,  un _foncteur_ "et" permettrait de fabriquer et(estPair, estPositif) qui serait une fonction sur les entiers. Et hop.

                                      Du coup, si les C++ ont leur propre signification pour "foncteur", ils en ont peut être une perso pour "fermeture", quel le reste du monde ne partage pas. Allez savoir. En tout cas ça ne facilite pas la discussion.

                                      ---

                                      Pour moi,les foncteurs de C++, c'est des objets qui font semblant d'être des fonctions qu'on peut appeler, parce qu'ils ont surchargé operator(). Pourquoi pas. Voila la traduction des exemples

                                      class Adder {
                                      private:
                                          int m_n;
                                        public: 
                                          Adder(int n) 
                                            : m_n{n}
                                            {}
                                          int operator()(int v) {
                                            return v + m_n;
                                          } 
                                        };  
                                      
                                      class AdderRef {
                                      private:
                                          int & m_n;
                                        public: 
                                          AdderRef(int & n) 
                                            : m_n{n}
                                            {}
                                          int operator()(int v) {
                                            return v + m_n;
                                          } 
                                        };  
                                      
                                      int main()
                                      {
                                        int n = 3;
                                        Adder a{n};
                                        AdderRef b{n};
                                        
                                        n = 4;
                                        
                                        std::cout << a(10) << std::endl;   // 13
                                        std::cout << b(10) << std::endl;   // 14
                                        return 0;
                                      }
                                      

                                      ok, ça pète pas trois guibolles à un canard, c'est laborieux comme tout. La capture de ce qui servira à évaluer l'appel de fonction, ça se fait à la mano via le constructeur (ou par des accesseurs si vous voulez). 

                                      Je dirais que les éléments du langage ne construisent pas une fermeture, mais que le programmeur s'est arrangé pour en bidouiller une quand même. On peut parler de fermeture en tant que "pattern" de programmation, mais pas comme mécanisme fourni par les "foncteurs" de C++, qui sont de bêtes objets.

                                      Alors que quand on écrit une lambda, évidemment, ce qui est indiqué comme devant être capturé est automatiquement stocké quelque part, sans qu'on ait besoin de le faire explicitement.



                                      -
                                      Edité par michelbillaud 28 octobre 2018 à 11:40:58

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        28 octobre 2018 à 12:04:21

                                        @MichelBillaud, je trouve ton code intéressant. Peux-tu le commenter au regard de ton propos ?

                                        @gbdivers, merci par avance pour ta réponse

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          28 octobre 2018 à 12:17:45

                                          Retour de fonction :
                                          * si le type de retour indique un objet sans référence, la valeur retournée est une pr-value.
                                          * si le type de retour est l-référence (donc utilise &), la valeur retournée est une l-value.
                                          * si le type de retour est r-référence (donc utilise &&), la valeur retournée est une x-value.

                                          Opération de conversion :
                                          static_cast<T>() : la valeur est une pr-value
                                          static_cast<T&>() : la valeur est une l-value
                                          * static_cast<T&&>() : la valeur est une x-value.

                                          Paramètre de fonction (ou création de variable)
                                          * le paramètre est une variable, donc est toujours une l-value, le paramètre peut recevoir des l-value ou r-value.
                                          *-* s'il a le type T ou const T, il reçoit tout type et le convertit par copie si nécessaire et possible.
                                          *-* s'il a le type T&, il ne peut que recevoir une l-value non constante qu'il va alors référencer.
                                          *-* s'il a le type T const&, il reçoit tout et va référencer ce qu'il reçoit.
                                          *-* s'il a le type T&&, il ne peut recevoir qu'une r-value (donc x-value ou pr-value) non constante qu'il va référencer.
                                          *-* s'il a le type T const&&, il ne peut recevoir qu'une r-value constante qu'il va référencer.
                                          Les règles ci-dessus peuvent être précisées dans les cas où T est une fonction, T est volatile, l'objet est volatile, le type T vient d'un paramètre template ou d'un concept, ou le cas d'une simple copie de variable ou bien T vaut auto. Mais cela reste globalement vrai, restons simple.

                                          Il reste le cas particulier qui nous intéresse ici où le paramètre a le type auto&& (paramètre de lambda ou variable créée) :

                                          auto&& var = ..............

                                          Cette ligne représente un des moyen d'avoir une transmission parfaite dans var.
                                          A droite du égal, c'est une pr-value, une l-value ou bien une x-value.
                                          On a beau avoir une transmission parfaite, toute variable dans laquelle on met une expression est une l-value, donc var est une l-value.
                                          Mais si on s’intéresse au type de var, on peut savoir si elle est un intermédiaire qui désigne une r-value :
                                          * type de var est T&& : alors l'expression était une r-value (donc une pr-value ou une x-value)
                                          * type de var est T&  : alors l'expression était une l-value.
                                          Attention pour bien comprendre la transmission parfaite, il est important préalablement de bien avoir compris tout ce qui est cité ci-avant.

                                          • Partager sur Facebook
                                          • Partager sur Twitter

                                          En recherche d'emploi.

                                            28 octobre 2018 à 12:37:58

                                            (J'aimerais que ce thread reste sur la question de yes man)

                                            @michelbillaud

                                            En soi, ca me choque pas que dans un domaine particulier (le C++), un terme a une acceptation spécifique. Je voulais juste savoir si tu utilisais le terme "fermeture" pour parler des lambdas, des foncteurs ou des 2. (Juste pour savoir ton usage, ce n'est pas une critique).

                                            Je n'ai pas trouvé "functor" dans la norme C++. Je me demande si ce n'est pas plus un usage que quelque chose dans la norme.

                                            @Dalfab

                                            Tu es en train de pourrir ma discussion avec yes man, sur ce que je veux lui montrer ;)

                                            @Yes Man

                                            Ne poses plus de question, donne le code de la fonction main.

                                            Tu devrais pouvoir donner ce code tout de suite, sans avoir besoin de faire de recherche sur internet, si tu as compris les lvalue et rvalue.

                                            -
                                            Edité par gbdivers 28 octobre 2018 à 12:39:41

                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              28 octobre 2018 à 14:20:23

                                              @gbdivers : ce que je peux en dire (mais qui ça intéresse d'avoir mon avis), c'est que le programmeur doit, avec les objets fonctionnels improprement appelés "foncteurs",  récupérer lui-même et stocker les éléments de l'environnement pour constituer une fermeture (en tant que pattern de programmation) qui servira à l'appel.

                                              J'ai jeté un oeil à mon vieux Stroustrup (le langage C++, 2ieme edition, 1991), il n'est pas question de "foncteur" ni d'objet fonctionnel. Il évoque le fait qu'on surcharge (), rien de plus.  On n'y trouve pas plus de cloture que de fermeture.  

                                              @Yes man de quel commentaire y a-t-il besoin ?

                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                28 octobre 2018 à 18:26:59

                                                @MichelBillaud, je reviendrai sur la question plus tard, après avoir suivi les conseils de gbdivers

                                                @daflab : merci pour ses conseils et connaissances apportées . J'ouvrirai un nouvel fil de discussio si j'y pense pour travailler sur ton long message en temps voulu.

                                                @gbdivers : pour l'exercice 1 :

                                                voici mon code actuel non terminé pour l'instant. J'ai supposé qu'un paramètre est soi une rvalue soit une lvalue (pas autre chose).

                                                Reste à pouvoir remplir le if de manière à caractériser une lvalue en un seul if. à priori, je cherche à voir comment faire ça.

                                                #include <iostream>
                                                
                                                 
                                                // declaration de f
                                                void f(int n) { 
                                                    if(n...)
                                                        std::cout<<"f a été appelé par une lvalue";
                                                    else
                                                        std::cout<<"f a été appelé par une rvalue";
                                                 }
                                                 
                                                int main() {
                                                    // appel de f avec une lvalue
                                                    int b{1};
                                                    f(b);
                                                 
                                                    // appel de f avec une rvalue
                                                    f(1);
                                                }

                                                EDIT : étant donné qu'une lvalue est une entité dont on peut prendre l'adresse , voici ce que viens de faire, avec une erreur renvoyée par mon compilateur :

                                                #include <iostream>
                                                
                                                
                                                // declaration de f
                                                void f(int n) {
                                                    if(&n)
                                                        std::cout<<"f a été appelé par une lvalue";
                                                    else
                                                        std::cout<<"f a été appelé par une rvalue";
                                                 }
                                                
                                                int main() {
                                                    // appel de f avec une lvalue
                                                    int b{1};
                                                    f(b);
                                                
                                                    // appel de f avec une rvalue
                                                    f(1);
                                                }
                                                8|error: the address of 'n' will never be NULL [-Werror=address]|




                                                -
                                                Edité par pseudo-simple 28 octobre 2018 à 18:41:57

                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  28 octobre 2018 à 19:15:27

                                                  @YES, man ta fonction f() commence par :
                                                  void f(int n) { ......
                                                  Dès cet instant tu as déjà perdu toute information du paramètre transmis. Ton n a reçu une copie de ce qui a été transmis et donc a irrémédiablement perdu l'information de r-value ou l-value.
                                                  Sans polluer l'exercice de gbdivers ^^; une piste possible serait d'avoir une signature de fonction mieux choisie ou peut-être de définir 2 fonctions f() qui "choisiraient" le type d'expression à recevoir. C'est à creuser...
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter

                                                  En recherche d'emploi.

                                                    28 octobre 2018 à 19:23:12

                                                    Je dois avouer que je pensais que tu allais bloquer sur le code de main. C'est déjà pas mal.

                                                    Maintenant, je te cite :

                                                    YES, man a écrit:

                                                    "Il est important de faire a différence entre les arguments et les paramètres, car les paramètres sont des lvalues, alors que les arguments qui servent à les initialiser peut être des ravalues ou  des lvalues" ......... jusque là, tout est ok pour moi. 

                                                    Un paramètre ("n" dans ton code) est toujours une lvalue...

                                                    Je te laisse chercher comment écrire correctement la fonction f.

                                                    ---------------------

                                                    Quelques remarques quand meme (meme si je sais que tu n'apprécies pas la critique...)

                                                    1. tu abordes des choses dans ton apprentissage sans avoir les bases pour les comprendre.

                                                    Tu lis un chapitre sur le perfect forwarding alors que tu ne comprends pas correctement les catégories de valeurs, que tu ne comprends pas la problème à laquelle répond le perfect forwarding.

                                                    Comment peux tu espèrer comprendre correctement ce que tu lis sans avoir les bases ?

                                                    2. tu n'es pas capable de juger quand tu as des lacunes, quand tu ne comprends pas le cours, ou que le cours dit n'importe quoi.

                                                    Tu passes ton temps a dire que tu peux lire un mauvais cours, que ce n'est pas grave, qu'il faut juste avoir du recul. Mais quand tu as "tout est ok pour moi" dans ton premier message, tu n'as pas réalisé que tu n'avais pas les bases pour comprendre ce que tu lisais.

                                                    Tu vois ici (j'espère) que tu te trompais depuis le début sur ce point : un débutant n'a pas le recul pour être critique sur un cours qu'il suit. Ne pas accepter cela, c'est un bon moyen de foirer son apprentissage.

                                                    3. Tu n'apprends pas correctement

                                                    Dans un apprentissage correct, on suit une progression pédagogique logique, où des notions de base sont vues avant d'aborder les notions qui en découlent. Mais ce n'est pas comme ca que tu fais. A lieu d'apprendre de A à Z, tu apprends C puis H puis K, puis tu reviens a B, puis tu poses des questions sur Z, pour revenir ensuite a E, etc.

                                                    La progression de ton apprentissage est dirigé par le hasard, en fonction de ce que tu lis, des questions que tu poses, de ce que tu crois comprendre. Tu n'as pas un apprentissage cohérent, tu apprends des éléments d'informations, mais sans lien entre eux.

                                                    4. On est aussi responsable de tes égarements d'apprentissage.

                                                    Un forum n'est pas un cours !

                                                    Quand on répond sur un forum, on ne vérifie tes connaissances de base (les prérequis), pour t'expliquer LA notion que tu as besoin de savoir à ce moment là, et on ne vérifie pas ensuite que tu as correctement comprise cette notion avant de passer a la suite.

                                                    On donne les éléments d'information par rapport a ce qu'on comprend de la question, du contexte, de ce qu'on a dire, etc. Cette discussion est un parfait exemple qui montre qu'un forum n'est pas un cours. On a des digressions sur les foncteurs et les lambdas. On a le message de Dalfab qui contient beaucoup d'informations d'un coup (informations correctement données, de facon concise, mais du coup difficile à assimiler).

                                                    Je te l'ai déjà dit que tu poses trop de questions, ce qui montre un problème dans ton apprentissage. 

                                                    @All

                                                    Pour ceux qui lisent cela et qui répondent a Yes, Man sur le forum. Je pense que ça serait une bonne idée... d'arrêter de lui répondre. Tout au moins de lui donner autant d'informations, qu'il ne peut pas assimiler.

                                                    Trop d'information nuit complètement à son apprentissage.

                                                    Si vous êtes d'accord avec ce que je dis, je propose de donner des exos simples, comme j'ai fait dans cette discussion, à chaque fois que Yes Man pose une question. Et de limiter les informations qu'on lui donne à ce qu'il peut comprendre.

                                                    -
                                                    Edité par gbdivers 28 octobre 2018 à 19:25:47

                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      28 octobre 2018 à 20:11:40

                                                      @daflab et autres : j'ai besoin d'un coup de pouce apparemment pour caractériser une rvalue et lvalue dans f.

                                                      Daflab avait l'air de proposer l'écriture de deux fonctions.

                                                      @all et gbdivers : je ne suis pas d'accord avec la position de gbdivers, qui a une position une nouvelle fois erronée sur le perfect forwarding me concernant.

                                                      Je n'ai pas dit que j'allais le comprendre tout de suite. Je sais qu'avant cela, la compréhension des rvalues et lvalues doit être bonne.

                                                      La preuve , c'est que dans le livre de Scott Meyers, j'en suis au tout début.

                                                      Les aides des autres m'apportent toujours. Donc gbdivers, ne muselle pas les autres, de grâce : ta pédagogie me plaît par petits exercices.

                                                      Mais laisse les autres faire ce qu'ils veulent, car j'apprécie toujours de lire leurs longs postes.

                                                      @gbdivers : je te répète ce que je t'ai dit : arrête de faire le gourou et chercher à imposer ta vision aux autres. ça ne passera pas avec moi, je te le redis. Mais j'insisterai et je continuerai car si j'avais écouté tes injonctions de stopper le cours de OC, je n'en serais pas là aujourd'hui à avoir autant progressé en C++.

                                                      Si tu veux pas aider (et je sais que ce n'est pas le cas), alors tu n'aides pas. Et c'est tout. Mais il y a beaucoup de personnes de bonne volonté, qui m'ont considérablement aidé à progresser , et cela continue toujours, donc arrête avec ton diktat de ta pédagogie.

                                                      Je suis en total désaccord avec toi sur plein de points et ça restera ainsi, sois en sûr tant que tu chercheras à t'imposer de la sorte sur le forum de OC. Encore une fois, ton savoir ne te donne aucune prééminence.

                                                      Mais d'un point de vue purement technique, je suis preneur de certaines choses que tu écris tant que tu ne dérives pas dans ton idéologie.

                                                      Merci à openclassrooms pour son cours, qui même dans son imperfection, m'a appris beaucoup de choses , et constitue une bonne entre matière au C++11 de Scott Meyers

                                                      -
                                                      Edité par pseudo-simple 28 octobre 2018 à 22:52:32

                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        29 octobre 2018 à 11:19:06

                                                        Comme je m'y attendais, tu es trop tétu pour accepter les critiques. C'est plus facile pour toi de dire que j'essaies d'imposer mon idéologie, plutôt que de remettre en question. Mais, que tu l'acceptes ou non, ce sont des faits :

                                                        • on voit dans cette discussion que tu n'as pas les bases pour comprendre le forwarding. Et donc encore moins le perfect forwarding.
                                                        • on voit dans cette discussion que tu n'es pas capable d'évaluer correctement tes connaissances et tes lacunes
                                                        • le fait que tu as posé des questions dans un nouvelle discussion alors que les réponses t'ont déjà été données ici montre que tu n'es même pas capable de comprendre les réponses qu'on te donne

                                                        Concernant le cours, ce que tu ne comprends pas (ou n'acceptes pas), c'est que si tu ne comprends pas quelque chose d'un cours, on peut te l'expliquer. Mais s'il y a quelque chose que tu n'as pas vu dans le cours, il faut que tu lises un cours correct. Or, toutes tes questions dans cette discussion sont sur des points que tu n'a jamais lu dans un cours. C'est pas un problème de compréhension. (A mon sens, tu n'es pas plus idiot qu'un autre. Si tu ne comprends, c'est parce que tu ne suis pas un cours correct, pas parce que tu as des problèmes pour comprendre).

                                                        Tant que tu n'accepteras pas cela, tu continueras à ne pas progresser en C++. (Contrairement a d'autres sur le forum, qui progressent mieux que toi)

                                                        -
                                                        Edité par gbdivers 29 octobre 2018 à 11:19:44

                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                          29 octobre 2018 à 12:21:19

                                                          Voici pour l'instant ce que j'ai fait et qui donne un problème d'ambiguïté à la compilation :

                                                          #include <iostream>
                                                          
                                                          void f(int n) {
                                                          
                                                                  std::cout<<"f a été appelé par une lvalue";
                                                           
                                                           }
                                                          void f(int&& n) {
                                                              //if(&n)
                                                                  std::cout<<"f a été appelé par une rvalue";
                                                              
                                                           }
                                                           
                                                          int main() {
                                                              // appel de f avec une lvalue
                                                              int b{1};
                                                              f(b);
                                                          
                                                              // appel de f avec une rvalue
                                                              f(1);
                                                          }
                                                          

                                                          Oui, j'ai clairement besoin d'explications (aide) pour bien comprendre comment traiter la différence

                                                          Merci par avance

                                                          -
                                                          Edité par pseudo-simple 29 octobre 2018 à 12:24:20

                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                            29 octobre 2018 à 12:30:37

                                                            @Yes, man:
                                                            Si tu commençais par nous donner ta propre définition (pas celle du livre hein ?) de ce qu'est une lvalue et une rvalue ?
                                                            On serait plus à même de te corriger.
                                                            • Partager sur Facebook
                                                            • Partager sur Twitter

                                                            C++ Scott Meyers, transmission parfaite

                                                            × 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