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 :

[tuple]Peut-on parcourir un tuple?


Sujet :

Boost C++

  1. #1
    Membre expérimenté Avatar de Nogane
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 241
    Par défaut [tuple]Peut-on parcourir un tuple?
    Bonjour,
    Je suis confronté a un problème que je pensai simple, et qui finalement ne semble pas l'être.
    - Parcourir un boost::tuple de type et de taille inconnue.
    En effet il n'y a pas d'iterateur, ni de BOOST_FOREACH, pour les tuple.
    De plus il y a bien un accesseur par index, mais l'index doit être connue a la compilation.

    Ma première idée été donc de faire quelque chose comme ceci:

    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
    #include <iostream>
    #include <boost/tuple/tuple.hpp>
    #include <boost/static_assert.hpp>
     
    using namespace std;
    using namespace boost;
     
    template<class T>
    void coutTuple(const T &myTuple)
    {
      static const int len = tuples::length<T>::value; //len est connu a la compilation
      BOOST_STATIC_ASSERT(len == 1);
      if(len > 0)
      {
        cout << myTuple.get<0>();
        if(len > 1) //donc cette contition est fausse, puisque len == 1
        {
          cout << myTuple.get<1>(); //Pourtant il y a quand meme une erreur ici
          if(len > 2)
          {
            cout << myTuple.get<2>(); //et ici
            //if(len > 3) etc...
          }
        }
      }
    }
     
    int main()
    {
      tuple<int> myTuple(21548);
      coutTuple(myTuple);
      return 0;
    }
    Ce n'est pas très joli, et la taille du tuple est limité, mais je pensai qu'au moins ça marcherais.
    Et bien non car le compilateur semble vouloir compiler les lignes dont il sait pertinemment qu'elle ne seront jamais exécutées. Ce qui me surprend un peu.

    En poussant un peu le bouchon j'ai testé ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    int main()
    {
      if(false)  
      {
        tuple<int> myTuple(21548);
        coutTuple(myTuple);
      }
      return 0;
    }
    Le problème reste exactement le même. Ce qui veux dire que mon compilo tente d'instancier coutTuple<tuple<int> > alors qu'il sait bien que cette fonction ne sera jamais appelé.
    (Je suis sur minGW 5.1.4, et le problème semble indépendant des option de compilation)

    Quelqu'un aurait t'il une solution?
    Ou au moins une explication?

  2. #2
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Attention, tu confonds pas mal de choses. A la base, le compilateur instancie ce qui est nécessaire. A ce moment, il ne sait pas encore si les conditions s'évaluent toujours à true ou false.
    Ce n'est que lors de la phase d'optimisation que certaines branches vont être supprimées.

    Si tu veux éviter l'instanciation, ta seule option est la spécialisation de template.

  3. #3
    Membre expérimenté Avatar de Nogane
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 241
    Par défaut
    Si tu veux éviter l'instanciation, ta seule option est la spécialisation de template.
    Merci beaucoup pour cette précision.
    Je suis justement entrain de tester une solution a base de spécialisation template.

  4. #4
    Membre expérimenté Avatar de Nogane
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 241
    Par défaut
    Bon j'ai eu du mal a trouver alors je vous donne la solution.
    (Je la posterai dans le forum "contribuez" si ça intéresse quelqu'un)

    Voila le header:
    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
    #ifndef FOREACHTUPLE_H_INCLUDED
    #define FOREACHTUPLE_H_INCLUDED
     
    #include <boost/tuple/tuple.hpp>
     
    template<int index, class T, class F>
    struct ForeachTuple
    {
      void operator()(const T &myTuple, const F &func)
      {
        using namespace boost;
        static const int tupleLen = boost::tuples::length<T>::value;
        func(myTuple.get<(tupleLen - 1) - index>());
        ForeachTuple<index- 1, T, F>()(myTuple, func);
      }
    };
     
    template<class T, class F>
    struct ForeachTuple<0, T, F>
    {
      void operator()(const T &myTuple, const F &func)
      {
        using namespace boost;
        static const int tupleLen = boost::tuples::length<T>::value;
        func(myTuple.get<tupleLen - 1>());
      }
    };
     
    template<class T, class F>
    void foreachTuple(const T &myTuple, const F &func)
    {
      ForeachTuple<boost::tuples::length<T>::value - 1, T, F>()(myTuple, func);
    }
     
    #endif // FOREACHTUPLE_H_INCLUDED
    Et voila comment l'utiliser:
    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
    #include <iostream>
    #include <boost/tuple/tuple.hpp>
    #include "foreachTuple.h"
     
    struct DisplayValue
    {
      template<class T>
      void operator()(const T &val) const
      {
        std::cout << val << std::endl;
      }
    };
     
    int main()
    {
      boost::tuple<int, int , int, double, char> myTuple(1, 2, 3, 4.5941, 'e');
      foreachTuple(myTuple, DisplayValue());
      return 0;
    }
    Ça fonctionne un peu comme le std::foreach, mais sur les tuple.

  5. #5
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Les opérations pour les tuples, c'est dans Boost.Fusion.
    http://www.boost.org/doc/libs/1_38_0.../for_each.html pour un for_each à l'exécution (peut aussi se faire à la compilation)

  6. #6
    Membre expérimenté Avatar de Nogane
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 241
    Par défaut
    Oui en effet. Je m'en suis rendu compte depuis. Pas facile a trouver, quand même.

  7. #7
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Comment ça pas facile ? T'arrives dans la doc de Boost.Fusion, tu vois direct dans le sommaire Algorithm > Iteration > Functions, tu cliques, puis tu cliques sur for_each, et t'y es.

  8. #8
    Membre expérimenté Avatar de Nogane
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 241
    Par défaut
    Oui mais faut-il encore savoir que ça se trouve dans boost.fusion
    Moi je cherchai bêtement dans boost.tuple
    Je n'ai hélas pas encore pris le temps de parcourir l'ensemble des bibliothèque de boost. Je ferais mieux de me dépêcher parce qu'il y en as de plus en plus!!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 07/08/2008, 10h42
  2. Réponses: 3
    Dernier message: 25/05/2007, 00h01
  3. [VB.NET]Peut-on parcourir dynamiquement un datagrid ??
    Par jeff.jfs dans le forum Windows Forms
    Réponses: 6
    Dernier message: 09/05/2006, 13h00
  4. Selection de tuples
    Par gguivarch dans le forum Requêtes
    Réponses: 2
    Dernier message: 11/07/2003, 15h27
  5. [Crystal Report] problème de plusieurs tuples à imprimer
    Par Jé_48 dans le forum SAP Crystal Reports
    Réponses: 2
    Dernier message: 19/06/2003, 14h40

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