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

Boost C++ Discussion :

expression lambda evaluee qu'une seule fois


Sujet :

Boost C++

  1. #1
    Membre confirmé

    Profil pro
    Inscrit en
    April 2005
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : April 2005
    Messages : 162
    Points : 536
    Points
    536
    Par défaut expression lambda evaluee qu'une seule fois
    Hello !

    Je ne comprends pas pourquoi dans le code ci-dessous, l'expression lambda n'est evaluee qu'une seule fois :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
      vector<int*> v(2);
      v[0] = 0;
      v[1] = 0;
     
      for_each(v.begin(), v.end(), _1 = new int);
    Si par contre, je travaille avec des int au lieu de int*, l'expression suivante est bien evaluee pour chaque element du vecteur (2 fois ici donc) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      vector<int> v(2);
      for_each(v.begin(), v.end(), _1 = _1+1);
    Si qqun avait une explication .....

  2. #2
    Membre émérite

    Inscrit en
    May 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : May 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    C'est possible avec boost.phoenix (une généralisation de boost.lambda)

    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
     
    #include "boost/spirit/include/phoenix.hpp"
    #include <algorithm>
    #include <vector>
     
    using namespace boost::phoenix;
    using namespace boost::phoenix::arg_names;
     
    int main()
    {
      vector<int*> v(2, NULL); 
      int i = 0; 
     
    // c'est bien new_ et pas new
      std::for_each(v.begin(), v.end(), arg1 = new_<int>(ref(i)++));   
     
      printf("%d %d\n", *v[0],*v[1]);
    }
    Mais à vrai dire, je n'ai pas d'explication, car je ne comprends absolument rien au fonctionnement interne de lambda ou phoenix.

  3. #3
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    June 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : June 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    C'est juste qu'en C++, la stratégie d'évaluation des arguments est stricte. Si on veut appliquer une lambda-expr à chaque élément d'un vecteur, il faut que d'une façon ou d'une autre on retarde le new, qui est le seul élément perturbateur ici. C'est pour ça qu'il y a un new_. Car sinon on fait un new int, et on va assigner ce même int* aux deux éléments du vecteur. Tu vois la différence ?

  4. #4
    Membre émérite

    Inscrit en
    May 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : May 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Aaaah oui, j'ai compris, merci

    En fait new_() appelle le constructeur d'une fonction-objet dont l'opérateur() fait un new. C'est cet opérateur() qui sera appelé autant de fois qu'il y a d'élément dans le for_each...

  5. #5
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    August 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : August 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Juste pour rappeler que des vraies expressions lambda commencent à être gérées par les compilateurs courants. Jusqu'ici, je me suis refusé à utiliser boost::lambda qui, bien qu'un merveilleux tour de force technique, restent un peu de l'ordre de la bidouille à mon sens.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  6. #6
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    June 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : June 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Citation Envoyé par Arzar Voir le message
    En fait new_() appelle le constructeur d'une fonction-objet dont l'opérateur() fait un new. C'est cet opérateur() qui sera appelé autant de fois qu'il y a d'élément dans le for_each...
    C'est tout à fait ça !

    Citation Envoyé par JolyLoic Voir le message
    Juste pour rappeler que des vraies expressions lambda commencent à être gérées par les compilateurs courants. Jusqu'ici, je me suis refusé à utiliser boost::lambda qui, bien qu'un merveilleux tour de force technique, restent un peu de l'ordre de la bidouille à mon sens.
    Boost.Phoenix est meilleure ! Et on est en train de la réimplémenter. Mais dommage qu'ils ne fassent pas de lambdas polymorphes pour 0x.

  7. #7
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    July 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : July 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Je plussoie pour boost.pheonix. Et pour les lambda polymorphique j'ai pas suivi mais c'est définitivement abandonné?
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  8. #8
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    June 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : June 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Pour 0x oui on dirait.

  9. #9
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    August 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : August 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par Goten Voir le message
    Je plussoie pour boost.pheonix. Et pour les lambda polymorphique j'ai pas suivi mais c'est définitivement abandonné?
    Ça n'en n'a jamais fait partie, nuance

    Pour l'instant, je ne pense pas que ce soit une si grosse perte. Des lambdas non polymorphiques vont déjà bien rendre service, et ils s'implémentent plsu simplement (si la proposition d'avoir des lambdas polymorphiques n'est pas passée, c'est qu'ils ne sont pas si simples que ça... En quoi, je n'en sais rien, je n'y étais pas, mais je crois bien que le ration intérêt/difficulté n'a pas été jugé rentable).

    J'ai un peu l'impression que si on ouvre la porte aux lambdas polymorphes, on ouvre aussi la porte aux fonction implicitement template (qui ont été proposées en même temps que auto, et je ne suis pas certain qu'on ai vu les conséquences.
    bool f(auto x, auto y) { return x<y; }

    Franchement, il faudra me montrer un exemple très convainquant d'utilisation de lambdas polymorphes pour me faire changer d'avis.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  10. #10
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    June 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : June 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Elles sont bien plus compliquées à intégrer dans le langage de par tous les conflits que ça pourrait entraîner, la résolution des surcharges d'opérateurs complètement tordues, etc. Bref, faire une implémentation robuste c'est un travail de titan. Y'a qu'à voir comment est construite Phoenix actuellement (on retrouvera les mêmes principes dans la prochaine version), et imaginer ça au niveau du langage

    Sinon j'avais pas vu les fonctions implicitement templates ! C'est sympa d'emprunter certaines idées de ce genre aux langages fonctionnels C++ va avoir l'air plus jeune

  11. #11
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    August 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : August 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par Alp Voir le message
    Sinon j'avais pas vu les fonctions implicitement templates ! C'est sympa d'emprunter certaines idées de ce genre aux langages fonctionnels C++ va avoir l'air plus jeune
    Sauf que quand ça a été proposé (en même temps qu'auto ?), ça a été assez mal reçu je crois (en gros, "c'est quoi ce truc !"). Mais c'était il y a longtemps, je ne me souviens plus trop des détails. Est-ce que ça réapparaître pour C++XX ? Je n'en sais rien.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

Discussions similaires

  1. Réponses: 6
    Dernier message: 20/09/2009, 21h45
  2. [IDE]Comment télécharger VS2005 Express une seule fois?
    Par zamine81 dans le forum EDI/Outils
    Réponses: 2
    Dernier message: 05/01/2006, 19h14
  3. Réponses: 1
    Dernier message: 19/03/2005, 23h47
  4. Réponses: 18
    Dernier message: 10/02/2005, 14h22
  5. Réponses: 2
    Dernier message: 30/11/2004, 12h48

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