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++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé

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

    Informations forums :
    Inscription : Avril 2005
    Messages : 162
    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 Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    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 confirmé

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    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 Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    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
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    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 confirmé

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    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.

Discussions similaires

  1. Réponses: 6
    Dernier message: 20/09/2009, 20h45
  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, 18h14
  3. Réponses: 1
    Dernier message: 19/03/2005, 22h47
  4. Réponses: 18
    Dernier message: 10/02/2005, 13h22
  5. Réponses: 2
    Dernier message: 30/11/2004, 11h48

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