IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

de l'intérêt des lambda


Sujet :

C++

  1. #1
    Expert confirmé

    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 382
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 382
    Points : 4 943
    Points
    4 943
    Par défaut de l'intérêt des lambda
    Bonsoir,

    loin de moi de nourrir un bon gros troll poilu, mais plus je lis des articles sur les lambda, plus je constate que c'est un truc inutile.

    je m'explique, par exemple à la lecture de http://herbsutter.com/elements-of-modern-c-style/

    prenons ce morceau de code auto i = find_if( begin(v), end(v), [=](int i) { return i > x && i < y; } );quel est l’intérêt de de mettre un lambda, on peut supposer que ce find_if ne risque pas d'être tout seul dans tout le code, avec autant de répétition du lambda, donc très mauvais niveau réutilisation.

    après on peut toujours faire comme dans l'exemple de 3DArchi (http://www.developpez.net/forums/d1160181/c-cpp/cpp/langage/fonction-lambda-parametre-fonction/)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    auto lambda =
          [](int i1, int i2)
       {
          return i1+i2;
       }
       ;
    et dans ce cas, quel est l'intérêt par rapport à un foncteur je dirai "traditionnel" ? si quelqu'un a une petite explication ...

  2. #2
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Bonsoir,

    Tu ne trouves pas que c'est quand même bien plus simple (aussi bien à écrire qu'à faire évoluer) que de devoir utiliser une classe (et donc lui trouver un nom) avec une fonction membre et un constructeur si l'on doit faire une capture ?

  3. #3
    Expert confirmé

    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 382
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 382
    Points : 4 943
    Points
    4 943
    Par défaut
    bah comme ça, non, je ne trouve pas ça plus simple (avis personnel, pas de justification), de plus que ça soit le foncteur et le lambda, il faut un nom de toute façon, de ce coté là ça change pas grand chose.

    après je vois un autre inconvénient qui vient de surgir, le foncteur, tu n'as pas à en instancier une ... instance; le lambda, soit tu en as un en local, qui risque d'amener une duplication tôt ou tard, soit en global ...

    après si c'est juste du sucre syntaxique, ça remue, selon moi, beaucoup d'air pour pas grand chose.

  4. #4
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Avec un foncteur tu as aussi une instance.

    Pour les lambda si tu l'utilises juste une fois tu n'as pas besoin de lui donner un nom.

    Ecrit un foncteur prenant en capture un seul élément, et après ajoute un deuxième élément en capture. Maintenant fait pareil avec une lambda, tu devrais voir que c'est quand même plus simple.

    Oui globalement ce n'est que du sucre syntaxique comme beaucoup d'utilisation d'éléments de syntaxe ajoutés au C++11. Peut-être que ceux qui font des maths théoriques y verront des choses plus fondamentales (mais là je peux pas t'aider ^^).

  5. #5
    Expert confirmé

    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 382
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 382
    Points : 4 943
    Points
    4 943
    Par défaut
    peut être bien que oui, peut être bien que non, je testerai ça plus tard dans la journée.

    entre temps je suis tombé la dessus : http://channel9.msdn.com/Events/PDC/PDC10/FT13
    et ben même après ça, je cherche encore le truc.

    ps: j'ai peut être compris quelque chose d'intéressant dans la vidéo, mais la syntaxe résultante est tellement tordu que ça en perd tout l'intérêt.

  6. #6
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    C'est vrai que pour les lambda, il y a un problème de duplication de code. En même temps, le code dupliqué sera en général extrèmement simple.

    De plus, les lambda ont la possibilité de travailler sur une capture (en plus des paramètres). Et je soupçonne que nous allons voir apparaitre du code qui s'auto-modifie, de cette manière :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    auto lambda1 = [](int i1, int i2) -> void { ... }
    auto lambda2 = [](int i1, int i2) -> void{ ... } // même prototype
     
    struct polylambda 
    {
      std::function<void(int,int)> process;
    };
     
    int main()
    {
      polylambda pl;
      if (std::string(av[1]) == "1")
        pl.process = lambda1;
      else
        pl.process = lambda2;
      pl.process(atoi(av[2]), atoi(av[3]));
    }
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  7. #7
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Citation Envoyé par Emmanuel Deloget Voir le message
    Et je soupçonne que nous allons voir apparaitre du code qui s'auto-modifie, de cette manière :

    //code
    Cette remarque me rends tout à fait perplexe. En quoi est-ce que le code présenté en exemple s'auto-modifie ? En quoi est-ce qu'il est différent d'une solution à base de pointeur de fonction qui est "apparue" il y a plus de trente ans.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    void lambda1(int i1, int i2)  { printf("lambda1\n");}
    void lambda2(int i1, int i2) { printf("lambda2\n"); }
     
    typedef void(*FuncVoidIntInt)(int, int);
     
    struct polylambda 
    {
      FuncVoidIntInt process;
    };
     
    int main(int * argc, char* argv[])
    {
      polylambda pl;
      if (strcmp(argv[1], "1") == 0)
        pl.process = &lambda1;
      else
        pl.process = &lambda2;
      pl.process(atoi(argv[2]), atoi(argv[3]));
    }

  8. #8
    Membre éprouvé

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Points : 1 086
    Points
    1 086
    Par défaut
    J'ai l'impression que l'intérêt des lambda-fonctions par rapport aux foncteurs est du même ordre que celui des opérateurs ternaires cond?vraie:fausse par rapport aux blocs if/else : un petit artifice de programmation qui peut faciliter la lecture du code, dès lors qu'on l'utilise sur des instructions raisonnablement courtes, triviales et peu susceptibles d'évoluer. Non ?

  9. #9
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par Arzar Voir le message
    Cette remarque me rends tout à fait perplexe. En quoi est-ce que le code présenté en exemple s'auto-modifie ? En quoi est-ce qu'il est différent d'une solution à base de pointeur de fonction qui est "apparue" il y a plus de trente ans.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    void lambda1(int i1, int i2)  { printf("lambda1\n");}
    void lambda2(int i1, int i2) { printf("lambda2\n"); }
     
    typedef void(*FuncVoidIntInt)(int, int);
     
    struct polylambda 
    {
      FuncVoidIntInt process;
    };
     
    int main(int * argc, char* argv[])
    {
      polylambda pl;
      if (strcmp(argv[1], "1") == 0)
        pl.process = &lambda1;
      else
        pl.process = &lambda2;
      pl.process(atoi(argv[2]), atoi(argv[3]));
    }
    Pareil en assembleur. Je me demande pourquoi ils ont inventé le C et les pointeurs sur fonction.

    Bien évidemment, le principe est exactement le même (à trois poils de taureau près : le pointeur de fonction implique une redirection supplémentaire qui n'est pas nécessairement impliquée par la lambda ; la lambda peut capturer une partie du contexte dans laquelle elle est créée).

    Ceci dit, je me suis mal exprimé ; mon commentaire voulait seulement souligner que l'intégration des lambda dans C++11 peut ammener au développement d'un nouveau paradigme de programmation en C++, qui se basera probablement sur un mix (méta-prog + lambda), et qui devrait ammener un vent nouveau dans ce domaine.

    Bien évidemment, l'exemple que j'ai donné est simpliste et de peu d'intérêt. Mais pensez à un système d'écoute d'évènements par exemple, ou la lambda joue le rôle d'une fonction de traduction d'un format de message spécifique vers un format utilisable par un handler spécifique (par exemple, les paramètres des messages WM_MOUSEMOVE -> (btnstate + point<int>)).

    Le problème n'est pas de savoir si quelque chose existait avant ou pas (y-a-t-il des choses que vous pouvez faire avec le nouveau standard C++ et qui était strictement impossible à faire avec l'ancien ? Qu'apporte C++ par rapport à Fortran 66 en termes de possibilités ? Strictement rien : tout programme écrit en C++11 peut être écrit en F66 ; par contre, l'écrire en F66 demandera 10 fois plus de temps et 10 fois plus d'énergie). Il s'agit de savoir si la fonctionnalité apporte un plus en terme d'expressivité, de sécurité d'utilisation et de simplicité de mise en oeuvre.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  10. #10
    Membre éprouvé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2009
    Messages : 552
    Points : 1 060
    Points
    1 060
    Par défaut
    Citation Envoyé par cob59 Voir le message
    un petit artifice de programmation qui peut faciliter la lecture du code, dès lors qu'on l'utilise sur des instructions raisonnablement courtes, triviales et peu susceptibles d'évoluer. Non ?
    Très juste pour une simple raison. Si ce n'est pas trivial, c'est difficile de le tester à part, contrairement à un foncteur...

  11. #11
    Expert confirmé

    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 382
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 382
    Points : 4 943
    Points
    4 943
    Par défaut
    @Emmanuel Deloget : je comprends bien ton point de vu, mais dans le cas du lambda, je ne vois pas de situation où son écriture facilite la vie du programmeur, et pire ni celle du relecteur.
    dans la vidéo que j'ai mis le lien un peu plus haut, l'auteur encapsule le corps d'un do...while dans un lambda, et ça devient illisible, et la finalité pas forcément évidente à saisir.
    ça s'oppose par exemple à auto : la finalité et la compréhension est immédiate, après la légitimité ça se discute, mais au moins on comprend sa présence.

    par contre j'ai une question à propos du point que tu soulignes sur la redirection supplémentaire; ça ferait pas plus partie des possibilités du compilateur à optimiser du code que sur les fonctionnalités du lambda?

  12. #12
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Les personnes qui ne voient pas l'interet des lambda (ou de tout autre features) devraient tout simplement les mettre en pratique dans un projet, voir dans quels cas ils sont utiles.


    Parcequ'ils sont très utiles.


    D'abord, supposer que les algorithmes des lambdas vont être réutilisés souvent est tout simplement faux. La plupart du temps, c'est la fonction dans laquelle on a utilisé l'algorithme qui est réutilisé, pas le foncteur/lambda utilisé dans l'algorithme.
    Cela dit, c'est par exépérience que je dis ça.

    Ensuite, rien n'empeche d'utilser un foncteur quand on en a besoin. Le fait est que c'est assez rare, d'où la simplification qu'apporte le lambda.

    Il y a des tonnes d'autres avantages aux lambda, mais c'est le plus évident dans la pratique (qu'il faut prendre avant d'avoir une idée clair de ce genre de feature) surtout si on utilise les algorithmes stl souvent ou qu'on en écrit soit même.

    Car oui l'un des gros avantages est que lorsqu'on écrit un algorithme, on a beaucoup moins peur de demander un foncteur à l'utilisateur. Après tout, chaque fois qu'on écrit un algorithme ou même une fonction membre qui aurait interet a demadner un "visiteur", on peut avoir tendance à éviter de demander un foncteur parceque c'est très très très chiant a écrire pour l'utilisateur (alors que la plupart des foncteurs qu'on écrit pourraient se résumer a une fonction libre d'une ligne - mais on perds des avantages non négligeables ).

    Maintenant qu'on a les lambda, c'est simple, on a aucune mauvaise raison de ne pas demander une fonction comme argument d'un algorithme quand le design de celui-ci parait évident.


    Pour avoir tenté l'expérience (avec modération!) sur plusieurs projets, ça "libère" incroyablement l'expression du code.

  13. #13
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Commencons par l'utilisation la plus simple : direct pour un algorithme sans capture.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    template<class F>
    void bar(F f)
    { f(0); }
     
    struct C
    {
    	void foo() const
    	{ bar([](int i){}); }
    };
     
    struct D
    {
    	struct F
    	{ void operator()(int i) const { } };
     
    	void foo() const
    	{ bar(F()); }
    };
    Personnelement j'aurais tendance à préférer la version lambda tant que le foncteur utilisé est simple, et c'est souvent le cas AMA. Sinon en effet un foncteur est peut-être plus lisible, ou du moins totalement personnel.

    Maintenant un exemple avec capture où l'utilisation est localisée à une seule fonction (éventuellement plusieurs fois) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    struct A
    {
    	void foo(int& p1, int& p2) const
    	{
    		auto l = [&p1/*ici*/](int i){};
    		l(0); l(1);
    	}
    };
     
    struct B
    {
    	struct F
    	{
    		int& rp1; /*ici*/
    		F(int& rp1/*ici*/) : rp1(rp1) /*ici*/ { }
    		void operator()(int i) { }
    	};
     
    	void foo(int& p1, int& p2) const
    	{
    		F f(p1/*ici*/);
    		f(0); f(1);
    	}
    };
    Les commentaires /*ici*/ signale les endroit à modifier si l'on a besoin de plus d'éléments dans la capture : 1 vs 4, j'aurais tendance à conclure que les lambda permettent une meilleur évolutivité du code.

    Pour l'histoire "simplifier la vie du lecteur" c'est juste qu'une évolution du langage va nécessairement donner du mal aux utilisateurs pour lire du nouveau code dans un premier temps (comme apprendre un nouveaux langage), ceci dit on a probablement le même effet quand on utilise pour la première fois certaines bibliothèques, celle de méta-prog par exemple.

  14. #14
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Il y a plusieurs problèmes avec ce que tu présentes. D'abord, perso je vois rarement du code qui construit un lambda et le réutilise direct, donc c'est pas vraiment démonstratif.

    En plus tes lambda son vides alors ça donne pas une très bonne idée de ce que ça donne dans du vrai code.

    Au delà de ça, tu te compliques la vie avec le second exemple : si tu captures avec [&] le compilateur ne va prendre (par référence) unique que ce que tu utilises dans la lambda et qui est dispo dans le scope au dessus de la lambda. Pareil pour la capture par copie.

  15. #15
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Voici un exemple de code réél (et un peu bordelique à vrai dire , mais bon) où j'ai beaucoup utilisé de lambda.

    Note : j'ai du mettre les for_each dans des fonctions séparées parcequ'ils sont accessibles depuis l'extérieur de la classe et que c'est le seul moyen de parcourir le contenu de la classe, ce qui évite d'avoir a exposer un conteneur oui ce genre de joyeuseté.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
            bool Project::save()
            {
                    using namespace boost::property_tree;
     
                    // fill it with properties that needs to be saved
                    ptree infos;
     
                    infos.put( "project.name", name() );
     
                    foreach_sequence( [&]( const Sequence& sequence )
                    { 
                            infos.add( "project.sequences.sequence", sequence.location().generic_string() );
                    });
     
                    foreach_edition( [&]( const EditionSession& edition_session )
                    { 
                            infos.add( "project.edition.session", edition_session.id() );
                    });
     
                    if( m_selected_session )
                            infos.add( "project.edition.selected",  m_selected_session->id() );
     
                    // TODO : add other informations here
                    // TODO : manage errors differently
     
                    try
                    {
                            namespace bfs = boost::filesystem;
                            const auto directory_path = m_location.parent_path();
     
                            // make sure the directory is available
                            if( !bfs::is_directory( directory_path ) )
                            {
                                    bfs::create_directories( directory_path );
                            }
     
                            bfs::ofstream filestream( m_location );
                            write_xml( filestream, infos );
                    }
                    catch( const boost::exception& e )
                    {
                            UTILCPP_LOG_ERROR <<  boost::diagnostic_information(e);
                            return false;
                    }
     
                    std::for_each( m_sequences.begin(), m_sequences.end(), [&]( std::unique_ptr<Sequence>& sequence )
                    { 
                            sequence->save(); 
                    });
     
                    std::for_each( m_edit_sessions.begin(), m_edit_sessions.end(), [&]( std::unique_ptr<EditionSession>& edition_session )
                    { 
                            const auto& file_path = directory_path() / path::EDITION_SESSION_FILE( edition_session->id() );
                            edition_session->save( file_path ); 
                    });
     
                    return true;
            }
     
            void Project::foreach_sequence( std::function< void ( const Sequence& sequence )> func ) const
            {
                    std::for_each( m_sequences.begin(), m_sequences.end(), [&]( const std::unique_ptr<Sequence>& a_sequence ){ func(*a_sequence); } );
            }
     
            void Project::foreach_edition( std::function< void ( const EditionSession& edition_session )> func ) const
            {
                    std::for_each( m_edit_sessions.begin(), m_edit_sessions.end(),  [&]( const std::unique_ptr<EditionSession>& a_session ){ func(*a_session); } );
            }

    Le truc qui m'ennuie avec les lambda actuelles (comme beaucoup le déplorent) c'est qu'ils ne detectent pas automatiquement le type des attributs quand on les passe à un algorithme. Les gens du standard disent que c'est possible mais que ça sera pour une autre version.


    EDIT : je me rends compte que ce code a bsion d'un poil de refactoring parcequ'il a été fait en plusieurs fois et ça se sent

  16. #16
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Citation Envoyé par Klaim Voir le message
    Il y a plusieurs problèmes avec ce que tu présentes. D'abord, perso je vois rarement du code qui construit un lambda et le réutilise direct, donc c'est pas vraiment démonstratif.
    Ca s'addresse à quel exemple ? Le premier avec la fonction bar ou le second avec les appels direct à f et l ? Dans les deux cas le but n'est pas de montrer une utilisation réel des lambda mais de voir les différences entre lambda et foncteur, or le passage et l'utilisation dans une fonction de l'un ou de l'autre sont identiques.

    Dans le premier exemple j'ai introduit une fonction bar pour illuster la construction de la lambda du foncteur directement à l'endroit d'utilisation, dans le second cas l'op suggèrait qu'une lambda / un foncteur peut être utiliser plusieurs fois, c'est ce que j'ai fait (j'aurais pu fait 2 fonction bar1 et bar2 et les utilisers une fois chaque une avec la lambda / le foncteur, mais je ne pense pas que ca apporte grand chose à la comparaison des deux syntaxes).

    Citation Envoyé par Klaim Voir le message
    En plus tes lambda son vides alors ça donne pas une très bonne idée de ce que ça donne dans du vrai code.
    Je vois pas trop ce que ca change, remplis les {} de la lambda ou de l'opérateur () si tu y tiens . Cependant j'ai quand même fait la remarque qu'avec du code "long/compliqué" l'utilisation d'un foncteur serait peut-être plus lisible.

    L'idée était ici de comparer les deux syntaxes, remplir les {} va augmenter les deux codes d'exactement la même manière (à quelques noms d'itentifieurs près), ca n'apporte rien à la comparaison.

    Citation Envoyé par Klaim Voir le message
    Au delà de ça, tu te compliques la vie avec le second exemple : si tu captures avec [&] le compilateur ne va prendre (par référence) unique que ce que tu utilises dans la lambda et qui est dispo dans le scope au dessus de la lambda. Pareil pour la capture par copie.
    Ca change pas la conclusion, les expliciter permet (AMA) de rendre plus clair le parallèle lambda/foncteur, mais c'est qu'un avis.

    Edit: Mon code (contrairement au tien) n'avait pas pour but de montrer une utilisation réel des lambda, mais de comparer les syntaxes lambda/foncteur. A contrario le tien présente une utilisation des lambdas, mais ne permet pas cette comparaison de manière direct

  17. #17
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Citation Envoyé par Klaim Voir le message
    Le truc qui m'ennuie avec les lambda actuelles (comme beaucoup le déplorent) c'est qu'ils ne detectent pas automatiquement le type des attributs quand on les passe à un algorithme. Les gens du standard disent que c'est possible mais que ça sera pour une autre version.
    Polymorphiques ? Si je me trompe pas ca a été refusé car incompatible avec l'ajout de la notion de Concept proposé à l'époque. Enfin, on a toujours boost::phoenix pour ca en attendant

  18. #18
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Citation Envoyé par Flob90 Voir le message
    Polymorphiques ? Si je me trompe pas ca a été refusé car incompatible avec l'ajout de la notion de Concept proposé à l'époque. Enfin, on a toujours boost::phoenix pour ca en attendant
    Pas exactement, mais c'est lié, en gros il faudrait une autre syntaxe et ils avaient pas le temps de travailler dessus alors ils ont dit "plus tard". Mais ya déjà pas mal de suggestions pour utiliser auto dans les attributs de lambda. Le souci c'est que dans ce cas il faut généraliser à toutes les fontions.
    Ya aussi des propositions dans ce genre là : http://cpp-next.com/archive/2011/11/...-pythy-syntax/

    Perso boost::phoenix c'est cool mais la syntaxe et les limitations font que ça m'est trop rarement utile...


    Concernant ton exemple, ce que je veux dire c'est si tu ajoutes un peu de code , même une ligne, dans le lambda et dans le foncteur, ça donne une meilleure idée pour comparer les deux "à la lecture".

  19. #19
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    C'est justement de cette article que je sais que c'est lié à une limitation liés aux concepts :
    nobody could figure out how to integrate polymorphic lambdas with concepts
    Personne n'a présenter d'intégration des lambdas polymorphique compatible avec les concepts
    Mais à vrai dire j'en sais pas plus ...

    C'est vrai que dès qu'on fait quelque chose d'un peu compliqué boost::phoenix demande de s'adapter à une nouvelle syntaxe (si c'est quelque chose de vraiment simple, la syntaxe est plus simple que celle du standard je trouve), mais on n'a pas réelement besoin de lambda polymorphique tout le temps non plus (*) (c'est d'ailleurs une des justifications du comité pour la non intégration des lambda polymorphiques je crois).

    (*) Un besoin réel, pas juste pour simplifier la syntaxe d'écriture de la lambda.

  20. #20
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Un avantage des lambda est de permettre de limiter la portée d'un traitement aux seuls endroits où on en a vraiment besoin. Un foncteur classique sera visible sur un scope plus important et viendra donc 'polluer' celui-ci.

    Je ne pense pas que son seul intérêt soit de remplacer un std::bind (même si les constructions avec un lambda peuvent être plus digestes). L'intérêt va émerger au fur et à mesure de l'identification des bonnes pratiques de son utilisation.

    Pour l'instant, comme Klaim, je les vois très clairement devenir indispensables dans les algos (STL ou autres), les visiteurs, pour créer des fabriques à la volée.

    En revanche, je m'en méfie dans les système évènementiel (et donc tout ce qui ressemble à du signal ou du observateur) car là, la lecture du code et le debuggage deviennent plus chaud.

    @Emmanuel : comme Arzar, je pense que ton exemple montre beaucoup plus l'intérêt de std::function que celui des lambda. std::function qui sont aussi quelque chose qui se propagent comme la misère sur le monde dans mon code.

Discussions similaires

  1. Performances : intérêt des vues ?
    Par Mr N. dans le forum Requêtes
    Réponses: 4
    Dernier message: 20/10/2005, 13h42
  2. Intérêt des TActionList
    Par Invité dans le forum C++Builder
    Réponses: 4
    Dernier message: 11/03/2005, 17h31
  3. [glut] de l'intérêt des listes
    Par khayyam90 dans le forum OpenGL
    Réponses: 3
    Dernier message: 26/07/2004, 10h35
  4. Quel est l'intérêt des Services Web ??
    Par silvermoon dans le forum Débats sur le développement - Le Best Of
    Réponses: 19
    Dernier message: 12/02/2003, 22h28
  5. [Technique] Intérêt des index
    Par ddams dans le forum Décisions SGBD
    Réponses: 10
    Dernier message: 04/11/2002, 15h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo