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

Langage C++ Discussion :

Paramètre template non typé


Sujet :

Langage C++

  1. #1
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut Paramètre template non typé
    Bonjour à tous,

    Je suis actuellement confronté à un problème, j'aimerais faire quelque chose mais je ne sais pas comment le faire, malgré tout je sais que c'est possible.

    J'ai une fonction template :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template < int value1, int value2>
    int fonction () ;
    Mais le nombre de paramètre template non typé devrait être illimité...

    On m'a montré le code suivant mais je n'ai pas compris :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    typedef a<1,2> t;
    fonction<t>() ;
    J'en déduis que de cette façon on peut également faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    typedef a<1,2,3> t;
    fonction<t>() ;
    Mais je n'ai aucune idée de comment récupérer "t" dans "fonction" et de ce que représente "a".

    Merci de votre aide.

  2. #2
    Membre Expert

    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 : 35
    Localisation : France, Doubs (Franche Comté)

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

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

    Regardes du coté de boost::mpl, ca pourras t'aider.

    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    //Une fonction template qui prends en paramètre une séquence ...
    template<class Seq>
    void foo()
    { 
        std::cout << mpl::at<S,2>::value;
        //... d'entiers (à cause du "value")
        //affiche le second entier (de type int) de la séquence
    };
     
    typedef mpl::vector_c<int,0,1,2,3> ma_sequence;
    foo<ma_sequence>();
    // ou si tu préfères
    foo<mpl::vecotr_c<int,0,1,2,3> >();
    Et la dernière ligne est bien l'objectif recherché.

    mpl::vector_c c'est une séquence d'entier connue à la compilation, comme std::vector qui est une séquence d'objet. Si tu veux voir comment est codé mpl::vector_c, plonges toi dans le code de boost::mpl (le "principe" est pas forcément difficile à saisir, mais ca peut se révèlé plus complexe et laborieux à écrire pour obtenir la même qualité que boost::mpl).

    NB: Pas certain que mon code compile, pas testé, cependant l'idée est là je pense.

  3. #3
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    C'est tout à fait ce genre de chose que je veux faire !

    Par contre j'ai été voir les mpl.hpp et c'est un vrai méli-mélo de macro...

    Vous n'auriez pas un exemple plus simple ou d'autres ressources ?

    Merci beaucoup.

    EDIT je viens de voir que je n'avais pas posté dans la section la plus approprié et je m'en excuse.

  4. #4
    Membre Expert

    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 : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Utiliser directement boost::mpl n'est pas enviseagble ? On n'est pas obliger de réinventer la roue à chaque fois.

    Je ne me risquerais pas à poster un implémentation de mpl::vector_c, mais je peux te montrer une structure de type list (le plus simple pour commencer je pense), avec les variadics :
    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
     
    template<int...>
    struct ListInt;
     
    template<int I, int... T>
    struct ListInt<I,T...>
    {
      static const int value = I;
      typedef ListInt<T...> Tail;
    };
     
    template<class Seq, size_t I>
    struct At
    { static const int value = At<typename Seq::Tail,I-1>::value; };
     
    template<class Seq>
    struct At<Seq,0>
    { static const int value = Seq::value; };
     
    template<class Seq>
    void foo()
    { std::cout << At<Seq,2>::value; }
     
    foo<ListInt<0,1,2,3> >();
    (Si tu as pas les variadics ca se fait mais le code est plus long à écrire et répétitif)

    PS: J'avais pas fait attention à la section, je déplace dans langage.

  5. #5
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    J'avais vu les variadics mais je ne peux pas les utiliser pour mon projet (qui est, en fait, un projet boost pour le google summer of code) car elles font partie de la norme C++0x.

    Enfin je pense que la librairie boost "preprocessor" est celle qui permet d'écrire ce genre de code. J'ai trouvé ce genre de fichier qui doit permettre les répétitions :

    http://svn.boost.org/svn/boost/trunk...ion/repeat.hpp

    Par contre utiliser toutes ces macros me semblent bien compliqué sans avoir compris le principe.
    Est-ce que tu pourrais m'expliquer comment ça fonctionne ?

    Merci beaucoup et bonne journée.

  6. #6
    Membre Expert

    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 : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Bonjour,

    Je réitère ma question : tu ne peux pas utiliser directement boost::mpl ? Ca sera bien plus simple.

    Sinon, tu as regarder la doc de boost, je suis certain que l'utilisation de ces macros y est expliqué, pas pour autant que recoder boost::mpl::vector_c sera simple ...

    PS: Sans variadics regardes les TyeList de Loki, ca se comprend mieux que mpl::list, et comme type tu mets des std::integral_constant<int, value> (classe facile à recoder si tu peux pas utiliser le C++2011).

    PS2: Pour recoder une list de type tu devrais trouver plein de doc sur internet, c'est assez classique. mpl::vector est moins classique mais plus performent en général (perf à la compilation).

    Edit: http://www.boost.org/doc/libs/1_47_0...doc/index.html (pour la doc de BOOST_PP_REPEAT par exemple)

  7. #7
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    Je peux directement utiliser boost::mpl à condition que pour l'utilisateur cette utilisation soit transparente (mais je n'ai pas trop de doutes à ce niveau là). Je suis tombé sur un bon article explicatif (si d'autres personnes passent par là : http://blog.csdn.net/prototype/article/details/196071).

    Mais bon boost::mpl semble tout de même bien compliqué.

    Merci tout de même ;-)

  8. #8
    Membre Expert

    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 : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Si j'ai bien compris l'utilisateur va devoir utiliser la fonction, c'est ca ? Dans ce cas je ne trouve pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    foo<mpl::vecotr_c<int,0,1,2,3> >();
    Compliqué à écrire !

    Tu peux rajouter une macro si tu y tiens :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    #define MACRO_foo(arg) foo<mpl::vector_c<int,arg> >();
     
    //Double parenthèse
    MACRO_foo((0,1,2,3))
    (Pas testé)

    Les TypeList c'est bien, mais c'est moins efficase qu'un vector, et je ne vois pas en quoi ca va être plus user-friendly que mpl (je dirais même que ca va être l'inverse) !

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Un vector_c est une typelist hein (sous le capot)

  10. #10
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    Ce à quoi j'aimerais arriver c'est ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    fonction<1,2,3,...>(param) ;
    Maintenant est-ce que c'est possible ?

  11. #11
    Membre Expert

    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 : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Avec les variadics oui, sinon il faut passer par une séquence de type, soit mpl::vector_c, soit une que tu codes à la main, mais tu n'y gagneras absolument rien AMA (enfin si tu peux apprendre des choses, mais ca sera probablement pas plus efficase ni user-friendly que mpl).

    Tu trouves vraiment ca génant d'avoir à écrire mpl::vector_c< et > en plus ? C'est encore raisonnable je trouve.

  12. #12
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    Oui j'aurais préféré éviter d'utiliser ça comme ça mais bon apparament pas le choix !

    Merci de vos réponses,

    Bonne soirée.

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Tu veux toujours pas reconsidérer Boost.PP ? :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #define M0(z,n,t) \
      template<BOOST_PP_ENUM_PARAMS(n,int A)>
     
    BOOST_PP_REPEAT_FROM_TO(1,5,M0,~)
     
    #undef M0

  14. #14
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    Je ne comprend pas bien où vous voulez en venir, désolé.

    Mais je suis prêt à utiliser Boost.PP si ça peut m'aider, j'ai déjà lu la doc mais je ne vois pas vraiment comme l'intégrer a ce je veux faire.

    Merci.

  15. #15
    Membre Expert

    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 : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    En fait tu peux en réalisant une macro par dessus et en utilisant quelque chose comme boost::preprocessor :
    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 <boost/mpl/vector_c.hpp>
    #include <boost/preprocessor/repetition.hpp>
     
    template<class>
    void foo_impl()
    { /*code utilisant la séquence de type*/ }
     
    void foo()
    { foo_impl<boost::mpl::vector_c<int> >(); }
     
    #define FOO_impl(z,n,unused) \
      template<int I BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, int I)> \
      void foo() \
      { foo_impl<boost::mpl::vector_c<int, I BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, I)> >(); }
     
    BOOST_PP_REPEAT(10,FOO_impl,~)
     
    #undef FOO_impl
    (codé testé)

    NB: Je ne pense pas maitriser ni mpl ni pp, donc il y a peut-être mieux comme code.

    Edit: Le temps que je tape et teste le code Goten avais donné la piste à suivre.

  16. #16
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    Punaise ça marche exactement comme je veux que ça marche ! Même si je sais pas du tout comment.

    Merci pour l'exemple, je vais l'analyser et le comprendre maintenant.

    Merci à vous deux.

  17. #17
    Membre Expert

    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 : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Une petite explication rapide (après tu prends la doc et tu tests, tu devrais comprendre ) :
    - La "signature" de la macro FOO_impl est imposé par l'utilisation de BOOST_PP_REPEAT mais tu peux oublier z et unused pour savoir ce que ca fait
    - On définit une macro dont le paramètre n indique le nombre de paramètres template entiers (il y en a n+1, le cas sans paramètres est traité avant)
    - BOOST_PP_ENUM_PARAMS(n, int I) repète le second argument n fois en indicent chaque élément, par exemple avec n = 3 :
    - BOOST_PP_COMMA_IF(n) sert à mettre une virgule si n n'est pas nulle, pour avoir une syntaxe valide
    - BOOST_PP_REPEAT(10,FOO_impl,~) le troisième argument ne sert à rien ici (il faut mettre quelque chose de valide, ~ par exemple) ca "déplie" la macro FOO_impl 10 en partant de 0 comme paramètre. Si à la place de 10 c'était 3 ca donnerait (en ne prenant en compte que le paramètre n)) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    FOO_impl(0)
    FOO_impl(1)
    FOO_impl(2)

  18. #18
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    Merci de vos explications, c'est effectivement plus clair.
    Par contre, une dernière question, toute bête (et j'espère que c'est la dernière..), une fois dans la fonction comment fais t'on pour accéder aux différentes valeurs passées en "paramètre" ?

    J'ai essayé beaucoup de choses comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    template <class h>
    void bar()
    {
      typedef h::type vec;
      boost::mpl::at<vec, 1>::value ;
    }
    Mais sans succès.

    Merci beaucoup !

  19. #19
    Membre Expert

    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 : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    #include <boost/mpl/vector_c.hpp>
    #include <boost/mpl/at.hpp>
     
    template<class Seq>
    void foo()
    { 
        std::cout << boost::mpl::at_c<Seq,2>::type::value;
    };
    Par exemple.

  20. #20
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    Bon je vous dérange encore mais je me sens vraiment c*n de ne pas comprendre ce qu'il m'arrive comme ça !

    Ca fonctionne bien pour :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    template <class h>
    void bar()
    {
      std::cout << boost::mpl::at_c<h , 1>::type::value ; 
    }
     
    //...
    //appel
    bar< boost::mpl::vector_c<int , 1,2,3> >();
    Mais ça me met un paquet d'erreur lorsque j'essaye avec les macros que vous m'avez montré plus tôt. Pourtant il me semble que c'est le même type, (dans l'erreur ci-dessous : Vector=boost::mpl::vector_c<int>.)

    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
    d:\boost_1_46_1\boost\mpl\vector\aux_\preprocessed\plain\vector10.hpp(82): error C2039: 'item1' : is not a member of 'boost::mpl::vector_c<T>'
    2>          with
    2>          [
    2>              T=int
    2>          ]
    2>          d:\boost_1_46_1\boost\mpl\vector\aux_\at.hpp(73) : see reference to class template instantiation 'boost::mpl::v_at<Vector,n_>' being compiled
    2>          with
    2>          [
    2>              Vector=boost::mpl::vector_c<int>,
    2>              n_=1
    2>          ]
    2>          d:\boost_1_46_1\boost\mpl\at.hpp(45) : see reference to class template instantiation 'boost::mpl::at_impl<Tag>::apply<Vector,N>' being compiled
    2>          with
    2>          [
    2>              Tag=boost::mpl::aux::vector_tag<0>,
    2>              Vector=boost::mpl::vector_c<int>,
    2>              N=boost::mpl::long_<1>
    2>          ]
    2>          d:\boost-sandbox\soc\2011\checks\libs\checks\example\modulus_example.cpp(42) : see reference to class template instantiation 'boost::mpl::at_c<Sequence,N>' being compiled
    2>          with
    2>          [
    2>              Sequence=boost::mpl::vector_c<int>,
    2>              N=1
    2>          ]
    2>          d:\boost-sandbox\soc\2011\checks\libs\checks\example\modulus_example.cpp(46) : see reference to function template instantiation 'void foo_impl<boost::mpl::vector_c<T>>(void)' being compiled
    2>          with
    2>          [
    2>              T=int
    2>          ]
    2>d:\boost_1_46_1\boost\mpl\vector\aux_\preprocessed\plain\vector10.hpp(82): error C2146: syntax error : missing ';' before identifier 'type'
    2>d:\boost_1_46_1\boost\mpl\vector\aux_\preprocessed\plain\vector10.hpp(82): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    2>d:\boost_1_46_1\boost\mpl\vector\aux_\preprocessed\plain\vector10.hpp(82): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    2>d:\boost-sandbox\soc\2011\checks\libs\checks\example\modulus_example.cpp(42): error C3083: 'type': the symbol to the left of a '::' must be a type
    2>d:\boost-sandbox\soc\2011\checks\libs\checks\example\modulus_example.cpp(42): error C2039: 'value' : is not a member of 'boost::mpl::at_c<Sequence,N>'
    2>          with
    2>          [
    2>              Sequence=boost::mpl::vector_c<int>,
    2>              N=1
    2>          ]
    2>d:\boost-sandbox\soc\2011\checks\libs\checks\example\modulus_example.cpp(42): error C2065: 'value' : undeclared identifier

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. paramètres pilote non plug and play
    Par alberico dans le forum Windows XP
    Réponses: 4
    Dernier message: 17/08/2006, 20h38
  2. Réponses: 4
    Dernier message: 10/05/2006, 10h36
  3. Déclarer un paramètre template comme friend
    Par YéTeeh dans le forum Langage
    Réponses: 4
    Dernier message: 11/04/2006, 14h00
  4. X paramètres templates
    Par Alp dans le forum C++
    Réponses: 8
    Dernier message: 04/04/2006, 22h10
  5. transformer un buffer non typé en string
    Par bjl dans le forum Langage
    Réponses: 6
    Dernier message: 07/01/2006, 12h14

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