Partage
  • Partager sur Facebook
  • Partager sur Twitter

Conseil 3, références universelles et std::forward

C++11 / C++14

    4 novembre 2018 à 16:12:34

    Salut OC ;)
    je sui en train d'étudier le conseil 3 appelé "comprendre decltype", page 28 du livre de Scott Meyers, j'ai besoin de votre aide pour comprendre un message de ce conseil 3 car il renvoie au conseil 25 , ce qui est donc beaucoup plus loin dans le livre et je n'en suis pas responsable :
    Voici la situation :
    J'ai besoin de votre aide spécialiste pour comprendre et avant de mettre le passage qui me bloque, je mets ce que j'ai compris d'abord   :

    A la base, le code non affiné proposé par Scott était :
    template<typename Container, typename Index>
    auto authAndAccess(Container& c, Index i) -> decltype(c[i])  /C++11
    {
        authenticateUser();
        return c[i];
    }
    Puis, sa seconde version :
    template<typename Container, typename Index>
    auto authAndAccess(Container& c, Index i)      //C++14
    {
        authenticateUser();
        return c[i];                               //Type de retour déduit à partir de c[i]
    }


    Cela, je comprends aussi.

    Puis, il est proposé la version suivante avec cette fois decltype(auto) qui permet de déduire
    le spécificateur de type de variable dans son intégralité :

    template<typename Container, typename Index>
    decltype(auto) authAndAccess(Container& c, Index i)
    {
        authenticateUser();
        return c[i];
    }




    Jusque là, je suis encore.

    Puis, il est envisagé le cas où un conteneur est passé en rvalue.
    Donc on envisage d' utiliser une référence universlle pour résoudre cela :

    template<typename Container, typename Index>
    decltype(auto) authAndAccess(Container&& c, Index i);



    Puis, voici à partir de quand j'ai besoin de votre aide pour comprendre :
        ...Nous allons donc conserver le passage par valeur. Nous devons cependant revoir
        l'implémentation du template afin qu'il tienne compte de l'avertissement concernant l'application
        de std::forward aux références universelles (voir le conseil 25) :

    template<typename Container, typename Index>
    decltype(auto) authAndAccess(Container&& x, Index i)
    {
        authenticateUser();
        return std::forward<Container>(c)[i];
    }

    Voici mes questions :

    1) de quels avertissements est-il question ?
    2) Quel est le problème ?
    3) std::forward est décrit au conseil 25. Donc, pouvez-vous m'exppliquer pourquoi on en parle ici, sa fonction générale, à quoi il sert et pourquoi on a besoin ?

    Merci pour toutes vos explications

    ps:  droits d'auteur : Programmez efficacement en C++, de Scott Meyers, (Dunod). Copyright 2016 Dunod pour la version française 978-2-10-074391-9 et 2015 Scott Meyers pour la version d'origine 978-1-491-90399-5

    -
    Edité par pseudo-simple 4 novembre 2018 à 16:23:03

    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      4 novembre 2018 à 19:56:21

      Sur téléphone c'est galère de répondre, mais ce lien pourra t'aider : https://eli.thegreenplace.net/2014/perfect-forwarding-and-universal-references-in-c

      • Partager sur Facebook
      • Partager sur Twitter
        4 novembre 2018 à 20:14:43

        Merci

        Ce lien avec plein de trucs en anglais , ne m'aide pas franchement. Car le std::forward est justement abordé beaucoup plus tard dans le livre comme je l'ai dit, au conseil 25. Et je ne veux pas lancer l'analyse  du std::forward dès maintenant, car ce serait top tôt.

        J'ai quand même été fait un tour au conseil 25, et j'ai compris que j'ai besoin de revenir au 3.

        Mais j'ai besoin d'une explication contextuelle sur ce point, une explication peut-être plus générale de l'intérêt de std::forward, qui ne rentre peut-être pas directement dans les détails.

        Merci

        -
        Edité par pseudo-simple 4 novembre 2018 à 20:36:02

        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          4 novembre 2018 à 20:24:28

          Quand on écrit un cours, on a souvent le choix entre trois options quand il s'agit d'une notion encore inconnue.

          • On la passe sous silence entièrement. Ça facilite l'écriture certes, mais le lecteur risque de ne pas comprendre ou apprendre certains points.
          • On l'explique entièrement, quitte à le perdre parce qu'on aborde des choses trop compliquées ou qui demandent trop de pré-requis.
          • On explique très rapidement, en indiquant qu'on y reviendra plus tard.

          Ici, on est clairement dans le troisième cas. Donc soit tu accepte de ne pas tout comprendre, soit tu veux savoir et donc tu vas lire ce dont ça parle.

          Ici, je te fournis un lien, en anglais certes. On ne peut pas échapper à cette langue, surtout si tu cherches des ressources de C++ moderne. Donc tu peux lire ce lien.

          Ensuite, si tu veux vraiment savoir, va lire la section 25. Je n'ai pas le livre sous la main, je ne peux pas savoir là maintenant de quoi elle parle, mais je parie que tu trouveras les réponses aux questions que tu te poses.

          C'est un peu compliqué de t'expliquer alors qu'en même temps tu ne veux pas lire ne serait ce qu'un peu du chapitre concerné. C'est assez paradoxal non ?

          -
          Edité par Anonyme 4 novembre 2018 à 20:26:54

          • Partager sur Facebook
          • Partager sur Twitter
            4 novembre 2018 à 20:45:19

            Ce livre n'est pas un cours. Le lecteur est sensé deja connaitre ces syntaxes, le but du livre est d'approfondir.

            Je t'ai deja dit que ce n'est pas un livre pour ton niveau.

            • Partager sur Facebook
            • Partager sur Twitter
              4 novembre 2018 à 21:04:42

              @Gbdivers, peux-tu m'aider ? J'ai déjà compris bon nombre de choses dans les conseils 1 et 2.

              Peux-tu m'expliquer un peu ce qu'il se passe dans le cadre de ma question ?

              Merci à toi ou à tout autre

              -
              Edité par pseudo-simple 4 novembre 2018 à 21:05:13

              • Partager sur Facebook
              • Partager sur Twitter
                4 novembre 2018 à 22:02:31

                Pour std::forward, c'était tout le sujet de la précédente discussion. Et on t'a déjà donné toutes les infos sur les categories de values, sur le forwarding et le perfect forwarding. Et je t'avais dit que tu pensais avoir compris, mais que ce n'était pas le cas. On voit le résultat ici : tu re-poses des questions auxquelles on a déjà répondu. Relis la discussion sur le perfect forwarding.
                • Partager sur Facebook
                • Partager sur Twitter
                  5 novembre 2018 à 9:45:07

                  Pour faire simple, le perfect forwarding sert principalement à prendre n'importe quoi en entrée et à le passer exactement de la même manière à une autre fonction. Prendre une "référence universelle" juste pour l'utiliser dans la fonction me parait inutile.

                  Exemple, je prends quelque chose que je veux passer à une autre fonction.

                  template <typename Value>
                  void take_and_notify(Value&& v)
                  {
                      // peu importe si v est une const-reference, une reference ou même une valeur, ce sera envoyé comme tel à take
                      take(std::forward<Value>(v));
                      notify();
                  }



                  • Partager sur Facebook
                  • Partager sur Twitter

                  git is great because Linus did it, mercurial is better because he didn't.

                    5 novembre 2018 à 11:18:46

                    decltype est le truc que je ne présente dans mes formations qu'à des publics déjà avancés, et en toute fin de session.
                    1- parce que c'est complexe
                    2- parce que l'on en a rarement besoin
                    • 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.

                    Conseil 3, références universelles et std::forward

                    × 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