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 :

Faire comme boost::variant


Sujet :

C++

  1. #1
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut Faire comme boost::variant
    Voici ce que je défini
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    template <typename A1>
    struct mastruct
    {
    	A1 f1;
    };
     
    template <typename A1,typename A2>
    struct mastruct
    {
    	A1 f1;
    	A2 f2;
    };
    Le compilo n'accepte pas. Pourtant les boost::variant sont parfaitement acceptés.
    Comprend pas...

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Variant ne fait pas ça... Ils jouent à grand coup de macro pour les paramètres templates mais y'a qu'une seule classe ,)
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

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

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template <
          typename T0_
        , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(typename T)
        >
    class variant
    cf : http://svn.boost.org/svn/boost/trunk...nt/variant.hpp

    Faut scroller jusqu'au milieu environ pour tomber sur ça.

  4. #4
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    J'ai vu le code de boost avec son usage abusif de preproc... sans trop comprendre.
    Je pense cependant qu'il y a plusieurs définitions de variant. Il y en a une vingtaine, le fichier include s'incluant lui-même une vingtaine de fois avec à chaque fois un param en plus dans BOOST_VARIANT_ENUM_SHIFTED_PARAMS() (mettez plus de 20 paramètres template dans une instance de variant<> et ça pête).
    Mais faisons simple.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    boost::variant<int,std::string> v1;
    boost::variant<long,short,char> v2;
    Le code qui précède est accepté par les compilos. J'aimerais juste imiter quelque chose de semblable. Vous voyez comment faire, même de manière minimaliste ? Une simple classe qui accepte 1 ou 2 paramètres template sera bien.

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Si tu est allergique à toute la machinerie de boost.prepocessor (parce que c'est ça qu'utilise variant derrière) et que tu veux être portable alors tu peux utiliser les typelists.
    Pour l'allusion à la portabilité je parle des variadics templates de la prochaine norme :p. (supporté par gcc).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    template<typename T, typename U>
    struct Typelist
    {
         typedef T head;
         typedef U tail;
    };
     
    struct NullType {};
     
    #define Typelist_1(arg1)  Typelist<arg1, NullType>
    #define Typelist_2(arg1, arg2) Typelist<arg1, Typelist_1(arg2)>
    ....
    Et si tu veux éviter du NIH alors tu peux regarder du côté de loki :p

    Remarque que si c'est juste pour deux arguments templates alors peut être tu pourrais envisager un truc comme ça ? :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template <typename T1, typename T2 = NullType>
    struct foo { 
    //...
    };
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  6. #6
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Je ne souhaite pas faire mais comprendre.
    Tu as cependant un peu éclairé ma lanterne, boost fait quelque chose comme ceci avec les variants (il n'utilise pas d'include récursifs comme je le pensais, j'ai confondu avec l'include in_place_factory.hpp).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    struct nulltype {};
     
    template <typename A1,typename A2=nulltype,typename A3=nulltype>
    struct mastruct
    {
     union {
    	A1 f1;
    	A2 f2;
    	A3 f3;
     };
    };
    boost::variant va jusque typename A20 si j'ai bien vu.

    La "machinerie" boost.preproc j'essaie aussi de la comprendre. Je n'arrive pas à faire l'émulation d'un FOREACH.

    PS: qu'est-ce NIH ?

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Ouaip, ça va jusqu'à 20 types mais c'est extensible via la macro BOOST_VARIANT_LIMIT_TYPES.

    Ca fait un moment que j'ai pas regardé comment est géré la liste des templates pour émuler les variadics templates, la dernière fois c'était sur boost.function. Pour boost.function il me semble que c'est vraiment que du prépocesseur, pas des typelist.




    NIH = not invented here.
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  8. #8
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Points : 588
    Points
    588
    Par défaut
    Si ton compilo le permet alors utilises les variadic templates et le template recursion plutôt que des macros.

  9. #9
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Comprendre, avais-je dis que je souhaitais comprendre ?
    Ça fait 15-20 que les macros C++ existent et je n'arrive pas à comprendre comment faire/simuler une bête boucle. Malgré qu'on dispose des exemples de boost sous les yeux, c'est une telle usine à gaz que j'arrive pas à comprendre comment c'est fait.

    Quant aux variadicmachins, encore faut-il les comprendre eux aussi
    Mais on verra ça après la release et le premier service pack de VS2010 (l'expérience montre qu'il est prudent d'attendre avec MS ).

  10. #10
    Membre éclairé
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Points : 858
    Points
    858
    Par défaut
    Voici une implémentation de boost::variant avec des templates variadiques. Je pense que c'est beaucoup plus lisible et compréhensible :
    http://git.berlios.de/cgi-bin/gitweb...d5df3c43b8e61a

    Ensuite, Boost utilise le préprocesseur pour émuler les templates variadiques. Mais l'idée de base est la même.
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  11. #11
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par camboui Voir le message
    Comprendre, avais-je dis que je souhaitais comprendre ?
    Ça fait 15-20 que les macros C++ existent et je n'arrive pas à comprendre comment faire/simuler une bête boucle. Malgré qu'on dispose des exemples de boost sous les yeux, c'est une telle usine à gaz que j'arrive pas à comprendre comment c'est fait.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #define REPEAT1(a, b) b(a)
    #define REPEAT2(a, b) b(a)REPEAT1(a,b)
    #define REPEAT3(a, b) b(a)REPEAT2(a,b)
     
    #define CAT_(a, b) a##b
    #define CAT(a,b) CAT_(a, b)
    #define REPEAT(n, a, b) CAT(REPEAT,n)(a,b)
     
    #define action(a) a+a+a
    REPEAT(2, x+y, action)
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  12. #12
    screetch
    Invité(e)
    Par défaut
    est ce que tu peux expliquer le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define CAT_(a, b) a##b
    #define CAT(a,b) CAT_(a, b)
    ?

  13. #13
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Ah voilà qui est plus parlant !

    pluzun avec screetch, pourquoi ne pas faire directement #define CAT(a,b) a##b ?

  14. #14
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    C'est pour regler un probleme d'expansion de macro. C'est un grand classique. J'ai pas le temps de donner une explication, mais voir glue et xglue dans les exemples de la norme (que ce soit C ou C++, cet exemple y est) pour ceux qui en dispose.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Voilà l'exemple de la norme pour ceux qui l'ont pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #define HIGHLOW "hello"
    #define LOW LOW ", world"
     
    #define GLUE(a, b)  a##b
    #define xGLUE(a, b) GLUE(a, b)
     
     
    GLUE(HIGH, LOW)
    xGLUE(HIGH, LOW)
    "L'appel" à GLUE va afficher "hello" car il concaténe les deux chaines de caractères HIGH et LOW ce qui donne HIGHLOW et le prépocesseur remplace ça en "hello"
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  16. #16
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut


    Cet exemple m'apprend deux choses:
    les fonctions sont évaluées avant leurs paramètres;
    les paramètres ne sont évalués qu'une fois.

    EDIT: ceci ne passe pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    GLUE( x, GLUE(HIGH,LOW) )
    Ce n'est pas convertit en xGLUE(HIGH,LOW) ?

Discussions similaires

  1. Faire comme les methode de JOptionPane
    Par romuluslepunk dans le forum AWT/Swing
    Réponses: 6
    Dernier message: 09/06/2006, 22h30
  2. Que faire comme étude ?
    Par Xo Sonic oX dans le forum Etudes
    Réponses: 7
    Dernier message: 03/06/2005, 15h51
  3. Que peux-t'on faire comme application ?
    Par lalystar dans le forum Java ME
    Réponses: 2
    Dernier message: 11/12/2004, 05h36
  4. [maintenance][performance] Que faire comme maintenance ?
    Par woodwai dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 06/11/2003, 15h39

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