Partage
  • Partager sur Facebook
  • Partager sur Twitter

C++ Contenu de plusieurs variables dans une seule

    20 novembre 2021 à 17:53:59

    Bonjour,

    J'ai plusieurs variables qui contiennent chacune un caractère. Par exemple la variable primo contient le caractère 'A', secundo contient 'B' et tertio contient 'C'. Je souhaiterai avoir une quatrième variable quarto qui contient 'ABC' ... Je ne sais comment procéder. Si quelqu’un connait un moyen pour y parvenir, ce sera avec grand plaisir que je le découvrirai et l’utiliserai.

    Bien à vous et cordiaux messages

    • Partager sur Facebook
    • Partager sur Twitter
      20 novembre 2021 à 18:16:23

      C'est pas bien clair tout ça ?!

      Tu veux : 1) un tableau de 3 caractères ou 2) une chaîne de caractère ?

      Pour le 1) tu peux utiliser un std::array de char ou std::vector de char et pour le 2) une std:string.

      • Partager sur Facebook
      • Partager sur Twitter
        20 novembre 2021 à 18:21:30

        const auto primo { "A"s };
        const auto secundo { "B"s };
        const auto tertio { "C"s };
        const auto quatro { primo + secundo + tertio };

        ?

        EDIT : correction des ' en " pour des strings. 's n'est pas valide.

        -
        Edité par gbdivers 22 novembre 2021 à 16:19:58

        • Partager sur Facebook
        • Partager sur Twitter

        Rejoignez le discord NaN pour discuter programmation.

          20 novembre 2021 à 23:11:04

          Les trois premier sont des caractères, c'est plutôt:

          const auto  primo{ 'A' };
          const auto  secundo{ 'B' };
          const auto  tertio{ 'C' };
          const auto  quatro{ std::string(primo) + secundo + tertio };
          // ou
          const auto  quatro{ std::string{} + primo + secundo + tertio };
          • Partager sur Facebook
          • Partager sur Twitter

          En recherche d'emploi.

            20 novembre 2021 à 23:19:47

            Pas précisé et c'est plus simple comme ca. Et il n'y a pas de constructeur de std::string qui prend juste un caractère, il faut écrire "std::string(1, primo)".

            Mais la réponse est tellement simpliste que je suppose que la question est mal posée.

            • Partager sur Facebook
            • Partager sur Twitter

            Rejoignez le discord NaN pour discuter programmation.

              22 novembre 2021 à 8:16:28

              gbdivers a écrit:

              const auto primo { 'A's };
              const auto secundo { 'B's };
              const auto tertio { 'C's };
              const auto quatro { primo + secundo + tertio };

              ?


              Décidément, je ne m'y fais pas à cette façon de coder avec des auto de partout. On ne sait pas de quoi on cause, c'est pas explicite. 

              Je préfère 3 char et un std::string et on n'en parle plus.

              • Partager sur Facebook
              • Partager sur Twitter

              Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                22 novembre 2021 à 9:11:44

                si il faut que les 4 var soit toujours a jour :
                sinon deux trois pointeurs ?

                char quatro [4] = { "ABC" };
                char * primo = &quatro[0];
                char * secundo = &quatro[1];
                char * tertio = &quatro[2];

                ou avec des references

                char quatro[] = { "ABC" };
                char &primo = quatro[0];
                char &secundo = quatro[1];
                char &tertio = quatro[2];
                



                -
                Edité par ox223252 22 novembre 2021 à 9:12:44

                • Partager sur Facebook
                • Partager sur Twitter

                la connaissance est une chose qui ne nous appauvrit pas quand on la partage.

                Un tuto sur les makefile et mon GitHub

                  22 novembre 2021 à 14:38:05

                  Merci, vous avez parfaitement répondu à ma requête!
                  • Partager sur Facebook
                  • Partager sur Twitter
                    22 novembre 2021 à 15:05:00

                    Fvirtman a écrit:

                    gbdivers a écrit:

                    const auto primo { 'A's };
                    const auto secundo { 'B's };
                    const auto tertio { 'C's };
                    const auto quatro { primo + secundo + tertio };

                    ?


                    Décidément, je ne m'y fais pas à cette façon de coder avec des auto de partout. On ne sait pas de quoi on cause, c'est pas explicite. 

                    Je préfère 3 char et un std::string et on n'en parle plus.


                    C'est un exemple dans lequel auto n'est pas approprié. On utilise auto quand on écrit du code générique, quand on ne sait pas de quel type il s'agit, ou quand on veut simplement "renommer une variable" pour plus de lisibilité, auquel cas on se fiche de donner le type :

                    // Ceci
                    foo(variable1, variable2, fonctionSuperLongue(parametre1, parametre2 + quelqueChose, parametre3));
                    
                    // peut se réécrire en
                    const auto& tmp = fonctionSuperLongue(parametre1, parametre2 + quelqueChose, parametre3);
                    foo(variable1, variable2, tmp);
                    • Partager sur Facebook
                    • Partager sur Twitter
                      22 novembre 2021 à 16:29:41

                      Fvirtman a écrit:

                      Je préfère 3 char et un std::string et on n'en parle plus.

                      Si on utilise des chars, on peut pas concatener directement comme dans mon code. (Tiens, je réalise que j'ai fait une erreur dans mon code :D )

                      Fvirtman a écrit:

                      On ne sait pas de quoi on cause, c'est pas explicite. 

                      C'est parfaitement explicite, puisque c'est le type de la littéral qu'on utilise pour initialiser.

                      Par contre, effectivement, ca change la lecture en C++, il faut prendre l'habitude de regarder la littéral plutôt que le type explicite. Ce dont on n'a pas l'habitude en C++. Mais en réalité, c'est ultra commun dans beaucoup de langages de programmation.

                      x = 0     // python
                      let x = 0 // JS ou Rust
                      $x = 0    // PHP

                      C'est qu'une question d'habitude.

                      JadeSalina a écrit:

                      C'est un exemple dans lequel auto n'est pas approprié. 

                      On ne va pas refaire le débat de AAA, mais utiliser auto dans un tel contexte peut être parfaitement approprié.

                      La raison est que quand on écrit "int i = 0", on écrit 2 fois le type (dans la littérale et dans la déclaration de la variable). Avec auto, on ne l'écrit qu'une seule fois et donc le code est plus robuste (= si on fait un changement, on a moins de risque d'oubli si le type est écrit une fois que 2 fois).

                      En réalité, tout le code peut être considéré comme générique, du point de vue de la maintenance du code. Et dans la très grande majorité des cas, on se fiche du type exact d'une variable. Pour ca que beaucoup de langage ne permettent pas d'écrire explicitement le type et ca ne pose pas de problème. On fait ça en C++ par habitude historique, pas pour de réelles raisons techniques la plupart du temps.

                      -
                      Edité par gbdivers 22 novembre 2021 à 16:35:13

                      • Partager sur Facebook
                      • Partager sur Twitter

                      Rejoignez le discord NaN pour discuter programmation.

                        22 novembre 2021 à 18:49:18

                        gbdivers a écrit:

                        La raison est que quand on écrit "int i = 0", on écrit 2 fois le type (dans la littérale et dans la déclaration de la variable). Avec auto, on ne l'écrit qu'une seule fois et donc le code est plus robuste (= si on fait un changement, on a moins de risque d'oubli si le type est écrit une fois que 2 fois).


                        C'est la porte ouverte à des erreurs du type "on crée un int au lieu d'un float" :

                        void bar(float a);
                        
                        int main() {
                          auto foo = 3;
                          bar(foo); // oops, on voulait créer un foo de type float
                                    // warning: implicit conversion from int to float
                        }
                        
                        

                        -
                        Edité par JadeSalina 22 novembre 2021 à 20:01:45

                        • Partager sur Facebook
                        • Partager sur Twitter
                          22 novembre 2021 à 19:22:59

                          void bar(auto a);
                           
                          int main() {
                            auto foo = 3;
                            bar(foo); // oops, on voulait créer un foo de type float
                                      // warning: implicit conversion from int to float
                          }

                          Fixed.

                          Plus sérieusement, si tu sais que le type que tu veux créé est de type float et que tu veux exprimer explicitement cela, tu peux le faire en utilisant exploitant "float" ou en utilisant une littérale de type float. Aucune de ces 2 approches n'est plus expressive que l'autre, c'est juste une question d'habitude.

                          void bar(float a);
                           
                          int main() {
                            auto foo = 3.0f;
                            bar(foo); // oops, on voulait créer un foo de type float
                                      // warning: implicit conversion from int to float
                          }

                          Et bien sûr que tu peux trouver des exemples qui posent problème avec auto. Tout comme il y a des exemples qui posent problème avec un type explicite.

                          En pratique, pour des codes aussi triviaux, c'est juste une question de préférence, il n'y a pas réellement d'impact technique.

                          • Partager sur Facebook
                          • Partager sur Twitter

                          Rejoignez le discord NaN pour discuter programmation.

                            22 novembre 2021 à 22:31:47

                            Je ferais une comparaison avec l'optimisation  :

                            Optimiser du code, c'est le rendre souvent moins lisible, et ça vaut le coup uniquement dans les zones critiques (5 ou 10% du code ?)

                            (je ne dis pas qu'il ne faut pas optimiser ou gaspiller des ressources, mais on peut privilégier la lisibilité)

                            Ici, avec auto tu parles de généricité (évidemment), mais tout doit il est générique ? A part 5 à 10% du code qui peut être générique, est il nécessaire de prévoir de généricité pour tout ? 

                            Quand tu écris "void bar(auto a)" je trouve déjà ça peu lisible, car selon d'ou tu viens tu ne sais pas de quoi tu causes. Je ne trouve pas ça lisible du tout.

                            J'ai eu un stagiaire extrémiste du auto et du template qui va avec qui voulait faire du générique partout et dans toute circonstance. Je trouvais son code illisible, indébuggable, non maintenable, et surtout générique pour des cas qui jamais ne changeront.

                            J'aime la lisibilité, savoir de quoi on cause, surtout pour toutes les parties qui n'ont pas à devenir génériques.

                            • Partager sur Facebook
                            • Partager sur Twitter

                            Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                              23 novembre 2021 à 0:42:46

                              (on est hors sujet par rapport à la discussion initiale :) )

                              Il faut bien voir que la question de la lisibilité et de la généricité en C++ est fortement influencé par son histoire. Beaucoup de langages ne permettent pas d'écrire le type explicitement et cela ne pose aucun problème. Quand on écrit "auto i = 0", si on trouve cela moins lisible, c'est juste qu'on a l'habitude d'avoir un type explicit en C++, mais quand on a l'habitude, ça ne pose pas de problème de lisibilité.

                              J'aime par exemple la syntaxe de Rust pour le typage explicite :

                              let i = 0;
                              let i: i32 = 0;

                              Ca exprime bien l'idée que par défaut, le compilateur sait très bien se débrouiller pour trouver le type à utiliser. Et un type explicite, c'est une contrainte supplémentaire que l'on met sur le type.

                              Et la question est alors : pourquoi limiter le type ? Quelle raison technique de faire ca ?

                              En C++, la question se pose aussi. Et on peut alors inverser ta question : pourquoi ne pas faire du générique par défaut ?

                              Quand on écrit par exemple

                              int sum(int, int);

                              On ne veut probablement pas définir "l'addition sur le type particulier int" mais "l'addition sur deux nombres". On écrit plus souvent la première version parce que la généricité en C++ a longtemps été pénible (avec les templates), mais pas parce qu'on souhaite exprimer "je veux que cette fonction s'applique que sur int et uniquement sur int. Pas unsigned, int16, float, double, etc".

                              On ne pense généralement pas en termes de types particuliers, mais de concepts génériques. La programmation générique n'est pas un moyen pour généraliser ce qu'on pense, mais une façon plus proche d'exprimer ce qu'on pense. (Pense par exemple a un algo qui parcourt un tableau. Tu conçois cet algo en fonction du type spécifique std::vector ou en fonction du concept abstrait de tableau, peu importe si c'est un vector, un [], un new[], etc ?)

                              Écrire :

                              auto sum(Arithmetic auto i, Arithmetic auto j);

                              est probablement plus proche de ce qu'on veut réellement exprimer quand on écrit une telle fonction sum.

                              Au final, aux questions "pourquoi ne pas faire du générique ?" et "est-ce que le code est moins lisible ?", la réponse est la même : parce qu'on n'a pas l'habitude de faire autrement en C++, pas pour de vrais raisons techniques. Et écrire "auto i =0" n'est pas non plus réellement justifié techniquement pour un code aussi simple ! Je fais comme ca pour prendre l'habitude d'utiliser la généricité, parce que je n'ai pas envie d'être contraints par des raisons historiques. Et en soi, je comprends que l'on n'ai pas envie de faire ce choix et qu'on préfère un typage explicite.

                              Il faut juste avoir conscience que c'est une question d'habitude et pas de choix techniques (pour des syntaxes aussi simples).

                              -
                              Edité par gbdivers 23 novembre 2021 à 0:45:14

                              • Partager sur Facebook
                              • Partager sur Twitter

                              Rejoignez le discord NaN pour discuter programmation.

                                23 novembre 2021 à 6:37:42

                                La différence entre le basic à ce niveau la, c'est que les variables déclarées sans type étaient atomiques.

                                Ici, auto peut être n'importe quoi y compris un type complexe.

                                Tu me prends l'exemple d'une fonction sum, bien sur c'est l'exemple des 5% dont je parlais qui se prête bien à la généricité.

                                Mais tous les autres cas de fonctions qui ne seront jamais génériques, quand tu arrives avec "auto" tu ne sais pas de quoi tu causes. 

                                Même l'exemple de l'auteur, il veut ranger 3 char dans un string, il va droit au but ! 

                                Bref, ce débat sera sans fin je pense. Mais tu vois autant auto  peut être pratique dans certains cas pour gagner du temps, autant en foutre de partout, c'est perdre en sémantique pour moi, surtout quand tous tes paramètres de fonction sont des auto, que tu ne sais pas d'ou tu viens.

                                • Partager sur Facebook
                                • Partager sur Twitter

                                Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                                  23 novembre 2021 à 18:03:12

                                  Tu te méprends sur mes intentions, je fais parti des gentils :) En aucun cas, je conseille "en foutre de partout".

                                  Ma démarche est plutôt : si on n'avait pas cet attachement/habitude au passé en C++, si on commençait le C++ maintenant tel qu'il est actuellement, quels choix ferions nous ?

                                  Ce que je constate en me posant cette question, c'est que :

                                  - le problème de lisibilité est fortement lié à ce qu'on a l'habitude de lire (ce qui peut nous pousser à rejeter des syntaxes juste parce qu'on n'en a pas l'habitude).

                                  - le rejet de la généricité est aussi fortement lié à l'historique du C++, du fait que les templates sont assez lourd à utiliser. 

                                  C'est la principale raison qui explique pourquoi j'ai utilisé auto dans mon premier code : pour prendre de nouvelles habitudes et que mes anciennes habitudes ne soient pas LE critère qui me fait choisir une syntaxe plutôt qu'une autre. Pour essayer de faire en sorte que mes choix soit basé sur des critères techniques et pas l'habitude. Je ne sais pas si j'y arrive, mais je sais que si je rejette une nouvelle syntaxe à cause de mes habitudes, je suis sûr d'échouer.

                                  auto en paramètre de fonction est équivalent à void* ou std::any : c'est avoir tout et n'importe quoi. Et comme void*/std::any, son utilisation est déconseillé. Donc a aucun moment, il faut comprendre mon propos dans le sens "remplaçons tous les paramètres de fonction par auto". Ca n'aurait pas de sens et comme tu le dis, cela a un vrai impact (négatif) sur la lisibilité du code.

                                  Par contre, un code comme :

                                  auto sum(Arithmetic auto i, Arithmetic auto j);

                                  me semble suffisamment générique et informatif pour que ce soit acceptable. Dans ce code, on sait que c'est un type arithmétique (int, float, double, peu importe le type concret) et c'est l'information dont on a besoin pour comprendre la fonction.

                                  Pour auto dans les déclarations de variables, cela va dépendre. Pour moi, "auto i = 0" ne pose pas de problème. "auto it = begin(v)" non plus, puisque le nom de la fonction et le nom de la variable donne (pour moi - mais ca serait discutable, tout le monde ne pense pas forcément "begin == itérateur") explicitement le type (un itérateur ici). "auto x = foo()" par contre pose problème, parce que le contexte ("foo") n'est pas assez explicite pour comprendre le type de x. Et je ne suis pas fan du typage explicite de la forme "auto x = static_cast<MyType>(foo())", j'écris "MyType x = foo()" (même si je comprend les arguments - qui me semblent valides - sur le pourquoi de l'utilisation de static_cast).

                                  Donc globalement, le but est justement de renforcement la sémantique et la réutilisation du code, en forçant à penser son code de façon plus générique. Pour moi, c'est un peu l'équivalent de ce que l'on fait quand on réfléchit sur le design de son code : on se force à découper notre code, pour gagner en qualité logicielle, en modularité, etc. 

                                  -
                                  Edité par gbdivers 23 novembre 2021 à 18:11:18

                                  • Partager sur Facebook
                                  • Partager sur Twitter

                                  Rejoignez le discord NaN pour discuter programmation.

                                    26 novembre 2021 à 8:34:22

                                    Lire   auto n = 12  

                                    N'a rien de plus compliqué que de lire  int n = 12.

                                    Dans les deux cas, si on veut vérifier le type de n, il faut lire la déclaration. 

                                    Et le type de 12 est évidemment int.

                                    ---

                                    L'introduction de auto a une influence sur le style. NE PAS LE METTRE,  ça a tendance à signaler qu'il est probable qu'auto ne fournirait pas ce qu'on veut. Donc relire de près pour trouver la subtilité qui fait que. Si on met auto, principe de moindre surprise, par définition c'est le type kivabien pour l'expression...

                                    Va falloir évoluer et arrêter de voir C++ comme le langage comme on l'utilisait dans les années 80 :-)

                                    Je dis ca, mais souvent, les plus ardents défenseurs de "la façon traditionnelle de faire", c'est des jeunes programmeurs avec quelques années de pratique. Suffisamment pour avoir fortement intégré la logique de ce qu'ils ont appris, pas assez de recul pour avoir vécu plusieurs changements de façon de voir.

                                    (Bon y a aussi le vieux con qui veut rien changer, par principe. Arrêtez de me regarder comme ça)

                                    -
                                    Edité par michelbillaud 26 novembre 2021 à 8:52:18

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      26 novembre 2021 à 10:27:21

                                      michelbillaud a écrit:

                                      Lire   auto n = 12  

                                      N'a rien de plus compliqué que de lire  int n = 12.

                                      Dans les deux cas, si on veut vérifier le type de n, il faut lire la déclaration. 

                                      Et le type de 12 est évidemment int.

                                      ---

                                      L'introduction de auto a une influence sur le style. NE PAS LE METTRE,  ça a tendance à signaler qu'il est probable qu'auto ne fournirait pas ce qu'on veut. Donc relire de près pour trouver la subtilité qui fait que. Si on met auto, principe de moindre surprise, par définition c'est le type kivabien pour l'expression...

                                      Va falloir évoluer et arrêter de voir C++ comme le langage comme on l'utilisait dans les années 80 :-)

                                      Je dis ca, mais souvent, les plus ardents défenseurs de "la façon traditionnelle de faire", c'est des jeunes programmeurs avec quelques années de pratique. Suffisamment pour avoir fortement intégré la logique de ce qu'ils ont appris, pas assez de recul pour avoir vécu plusieurs changements de façon de voir.

                                      (Bon y a aussi le vieux con qui veut rien changer, par principe. Arrêtez de me regarder comme ça)

                                      -
                                      Edité par michelbillaud il y a environ 1 heure

                                      Et si au lieu de mettre 12 en dur on appelle une fonction ? Que se passerait-il si le type de retour change ? À ce moment là le code qui utilise "n" supposait peut être que c’était un int, et c’est donc maintenant faux. Si tout était générique de bout en bout ça aurait du sens, mais si on code une fonction qui a des variables locales, on a peut être envie de "fixer" le type de manière à ne pas avoir de mauvaises surprises si l’initializer change, et de rendre explicite le fait que la fonction veut utiliser un "n" de type int uniquement. 

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        26 novembre 2021 à 11:38:09

                                        @JadeSalina, un compilateur correctement configuré est ton ami.
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                        Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                          26 novembre 2021 à 11:53:04

                                          Pour en revenir au problème :


                                          Sans chercher midi à 14 heures, passer par un tableau temporaire de caractères terminé par le caractère nul

                                          char x = 'a';
                                          char y = 'b';
                                          char z = 'c';
                                          std::string chaine;
                                          	
                                          char tableau[] = {x, y, z, '\0'};
                                          chaine = tableau;
                                          



                                          JadeSalina a écrit:

                                          Et si au lieu de mettre 12 en dur on appelle une fonction ? Que se passerait-il si le type de retour change ? À ce moment là le code qui utilise "n" supposait peut être que c’était un int, et c’est donc maintenant faux.

                                          Un exemple sérieux pour mesurer la plausibilité de cette effrayante perspective ?

                                          Vous je sais pas, mais le type de retour de mes fonctions, il change pas tout seul, mais parce que je décide de le changer (ce qui est rare, d'ailleurs).

                                          Si le type de retour de la fonction change, et que ça rend auto inadapté du coté appelant,  c'est que le code appelant était spécifique, et qu'il faudra le changer de toutes façons.  Quand je décide de changer un truc, je regarde de suite toutes les conséquences.

                                          > si on code une fonction qui a des variables locales, on a peut être envie de "fixer" le type de manière à ne pas avoir de mauvaises surprises si l’initializer change, et de rendre explicite le fait que la fonction veut utiliser un "n" de type int uniquement.

                                          Un exemple concret ? "on aurait peut être envie", ça ne me suffit pas comme argument, parce que ça ressemble trop à "on aurait envie de pas mettre auto, alors on met pas auto, parce que si on mettait auto, on serait pas content".

                                          -
                                          Edité par michelbillaud 26 novembre 2021 à 12:13:55

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            26 novembre 2021 à 14:34:20

                                            mauvaise lecture ^^

                                            -
                                            Edité par ox223252 26 novembre 2021 à 15:46:51

                                            • Partager sur Facebook
                                            • Partager sur Twitter

                                            la connaissance est une chose qui ne nous appauvrit pas quand on la partage.

                                            Un tuto sur les makefile et mon GitHub

                                              26 novembre 2021 à 15:28:48

                                              ox223252 a écrit:

                                              michelbillaud a écrit:

                                              Un exemple sérieux pour mesurer la plausibilité de cette effrayante perspective ?


                                              Bien d'accord avec toi, si le retour de ta fonction change, alors il faut revoir tout le code qui y est lié sinont tu vas avoir des effets de bords qui peuvent etre catastrophique.

                                              Sauf si les appelants stockent la valeur de retour dans une variable avec un type explicite, auquel cas si une conversion implicite n’est pas possible, le compilateur nous le dira. Alors qu’avec auto, ça peut passer et ce sera à nous d’aller vérifier manuellement tous les appelants au lieu de laisser le compilateur nous indiquer le problème 

                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                26 novembre 2021 à 15:47:47

                                                Même si la conversion implicite est possible, le compilateur nous le dira sous forme de warning.

                                                C'est à vous de lire les warning, pas besoin de vérifier "à la main".

                                                "auto", c'est de l'inférence de type, pas des types dynamiques.

                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                                  26 novembre 2021 à 16:46:04

                                                  JadeSalina a écrit:

                                                  Et si au lieu de mettre 12 en dur on appelle une fonction ? Que se passerait-il si le type de retour change ?

                                                  Ca, ca s'appelle une régression ...

                                                  Car il faut bien te dire que, à partir du moment où une fonction existe, qu'elle renvoie une valeur ou non ne changera rien, c'est qu'elle est utilisée pour apporter une solution donnée à un besoin donné dans une situation donnée.

                                                  Cela implique qu'une fonction qui existe est forcément utilisée au moins une fois dans le cadre du besoin qui nécessitait qu'on développe cette fonction.  Seulement, en tant que développeur de la fonction, on ignore totalement combien de fois notre fonction sera appelée au final.

                                                  Elle peut n'être appelée qu'une seule et unique fois, tout comme elle peut être appelée cinq ou dix fois ... ou cent cinquante fois... vas savoir.

                                                  Si l'on vient à changer le type de la donnée renvoyée par une fonction, ce n'est donc pas seulement le seul cadre dans lequel la fonction a été développée qui change, mais bien le cadre de l'ensemble des endroits où la fonction sera appelée qui viendra à changer.

                                                  Il y a donc trois possibilités distinctes:

                                                  • Soit, nous sommes face à un besoin différent qui n'invalide absolument pas le besoin "d'origine" mais qui nous impose donc de garder la "première version" de notre fonction (en plus d'en rajouter une "deuxième version" pour répondre aux nouveaux besoins)
                                                  • soit le besoin d'origine était mal défini, ce qui justifie le changement du type de la donnée renvoyée, mais qui implique également de s'assurer que la modification sera "suivie d'effets" pour l'ensemble des endroits où l'on fait appel à la fonction
                                                  • soit, enfin, la modification ne fait que refléter une différence strictement interne (on passe d'une std::list à un std::vector, par exemple), et le type de la donnée renvoyée est simplement une abstraction permettant d'offrir "un certain nombre" de services qui lui sont propres (un itérateur, selon mon exemple)

                                                  Des trois cas cités, il n'y a guère que le troisième qui puisse réellement justifier le fait que le type de donnée renvoyé par une fonction puisse changer "en toute impunité" et sans risquer de devoir adapter le code existant pour l'ensemble des points du code où notre fonction serait appelée.

                                                  Et encore, quand je dis "en toute impunité", ca reste malgré tout  très relatif, car, si notre  abstraction (la notion d'itérateur, dans le cas présent) permet effectivement des similitudes comme le passage à  l'élément suivant ou la représentation d'un élément "qui suit le dernier élément existant", on retrouve malgré tout des possibilités qui n'existent pas pour certaines de ces abstractions, comme le fait de pouvoir prendre l'élément qui se trouve "N éléments plus loin".

                                                  Auto et l'inférence de types sont des outils très puissants, mais ils restent malgré tout des outils.  Et plus les outils sont puissants, plus il faut veiller à les utiliser "à bon escient".

                                                  Quand auto permet effectivement de ne pas dépendre de "futiles détails d'implémentation" qui sont toujours susceptibles de changer pour une raison ou une autre, nous aurions sans doute tors de nous en priver si, grâce à  lui, il est possible de rendre le code "plus flexible" et plus "résistant" face à  ses changements.

                                                  Mais, si on décide de mettre du auto "partout, tout le temps et pour n'importe quelle raison", cela devient presque aussi contre productif que de décider que l'on n'utilisera jamais que des vis de 4.5mm de diamètre et de 45mm de long: ces vis seront parfois suffisantes et nécessaires, parfois largement trop grande et d'un diamètre disproportionné, parfois largement trop petite et d'un diamètre insuffisant (sans même compter sur la possibilité de mettre des clous dans certaines circonstances)

                                                  • 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
                                                    26 novembre 2021 à 16:46:42

                                                    Par "implicite" je voulais dire qui se fait sans problème ni warning, par exemple si ça fait appel à un opérateur de conversion ou des promotions de type
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      26 novembre 2021 à 16:51:36

                                                      michelbillaud a écrit:

                                                      NE PAS LE METTRE,  ça a tendance à signaler qu'il est probable qu'auto ne fournirait pas ce qu'on veut. Donc relire de près pour trouver la subtilité qui fait que. Si on met auto, principe de moindre surprise, par définition c'est le type kivabien pour l'expression...

                                                      Ou que le dev n'aime pas auto. Ou que le code a été écrit avant auto. Ou que les devs ont des habitudes de codage.

                                                      C'est l'argument derrière le "auto x = static_cast<MyType>(foo())" dont j'ai parlé.

                                                      int foo();
                                                      
                                                      float x = foo(); // erreur ou volontaire ?

                                                      On ne sait pas simplement en lisant le code si c'est volontaire ou si c'est un oubli lors d'une mise à jour de foo. Avec auto + static_cast, c'est explicite que c'est un choix volontaire. (Déjà parce que personne n'utiliserait une syntaxe aussi lourde par négligence).

                                                      Mais c'est une syntaxe que je n'utilise pas, comme beaucoup j'imagine.

                                                      JadeSalina a écrit:

                                                      le code qui utilise "n" supposait peut être que c’était un int, et c’est donc maintenant faux.

                                                      Et si on utilise un type explicite au lieu de auto, que le type de retour de la fonction change et que l'on oublie de mettre à jour le code utilisateur ?

                                                      Dans tous les cas, utiliser un type explicite ou auto peut poser des problèmes, selon le contexte. Ce n'est pas un argument contre auto. Ni un argument pour auto.

                                                      JadeSalina a écrit:

                                                      au lieu de laisser le compilateur nous indiquer le problème 

                                                      Si le type change drastiquement (par exemple int qui devient optional<int>), oui, il n'y aura pas d'erreur du compilateur a la ligne avec auto. Mais il y en aura dans les lignes suivantes.

                                                      En vrai, utiliser auto ne sera généralement pas un problème. Ni ne pas l'utiliser... utiliser auto est souvent fait pour des raisons de simplification du code, pour ne pas écrire un type trop long. Pas parce que cela apporte un réel bénéfice technique. Et c'est bien pour cela que auto n'est pas utilisé partout, ça n'apporte pas grand chose.

                                                      • Partager sur Facebook
                                                      • Partager sur Twitter

                                                      Rejoignez le discord NaN pour discuter programmation.

                                                      C++ Contenu de plusieurs variables dans une seule

                                                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                      • Editeur
                                                      • Markdown