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 :

[Template] Spécialisation partielle d'un template


Sujet :

Langage C++

  1. #21
    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
    Citation Envoyé par 3DArchi Voir le message
    Je suis comme Kurisu. Je ne vois pas comment tu fais pour lui passer le paramètre à ta classe T1 ou T2. Il me manque une étape.
    Comment ça ?

    @loufoque : c'est possible ce que je tente d'expliquer, non ?

  2. #22
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Alp Voir le message
    Comment ça ?
    Ben le problème, c'est que tu peux pas écrire void p. Or à un moment ou à un autre, je ne vois pas comment tu fais pour contourner la contrainte.

  3. #23
    Membre averti
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Points : 392
    Points
    392
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Ben le problème, c'est que tu peux pas écrire void p. Or à un moment ou à un autre, je ne vois pas comment tu fais pour contourner la contrainte.
    Si seulement. En fait, c'était mon problème initial, que de pas pouvoir nommer un paramètre void.
    Maintenant, mon problème a changé: je ne peux pas avoir un deuxième paramètre qui soit void. (En fait, j'ai besoin d'un autre paramètre, en dehors de celui de la classe parente qui peut être void, pour rester fidèle le plus possible au principe de RAII).

    Pour revenir, mon problème initial, c'était de comment éviter d'avoir à écrire du code redondant. Je m'explique: selon la classe parente, le constructeur de classe parente peut ou ne pas prendre de paramètre.
    Or il est impossible de spécialiser partiellement une fonction, qui serait ici le constructeur du template intermédiaire InstanceOf<>, pour prendre aucun ou un paramètre.
    Mais je peux spécialiser partiellement le template pour le cas d'un paramètre vide.
    Seulement, pour cela, je dois repeter tout le code en dehors du constructeur, ce qui entraîne des redondances.

    Voilà, pour l'instant je m'y suis pris en réduisant au maximum le code restant du template InstanceOf<>, mais ca ne me convient toujours pas. Il doit y avoir une solution plus élegante, comme celle en D que j'ai postée plus haut.

    Puis, pour ce qui est de la metaprogrammation avec if_<> ou enable_if<>, je n'arrive pas à saisir les exemples sur le site de boost, donc une explication plus en profondeur serait la bienvenue.

  4. #24
    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
    if_ ou enable_if permettent d'écire ou non un code selon la valeur d'un booléen statique membre d'une structure/classe.

    Par contre, je viens de penser à une chose : et si tu utilisais une typelist ?
    Tu mets ainsi autant de types que tu veux dedans, tu spécialises à ta guise.

  5. #25
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    boost/mpl/if.hpp:
    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
    template<
          bool C
        , typename T1
        , typename T2
        >
    struct if_c
    {
        typedef T1 type;
    };
     
    template<
          typename T1
        , typename T2
        >
    struct if_c<false,T1,T2>
    {
        typedef T2 type;
    };
     
    template<
          typename BOOST_MPL_AUX_NA_PARAM(T1)
        , typename BOOST_MPL_AUX_NA_PARAM(T2)
        , typename BOOST_MPL_AUX_NA_PARAM(T3)
        >
    struct if_
    {
     private:
        typedef if_c<
              T1::value
            , T2
            , T3
            > almost_type_;
     
     public:
        typedef typename almost_type_::type type;
    };
    Je comprend: boost::mpl::if_<true_,T1,T2>::type vaut T1 et boost::mpl:if_<false_,T1,T2>::type vaut T2. En aucun cas, j'ai du code en plus ou en moins!

    De la même façon:
    boost/enable_if.hpp:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      template <bool B, class T = void>
      struct enable_if_c {
        typedef T type;
      };
     
      template <class T>
      struct enable_if_c<false, T> {};
     
      template <class Cond, class T = void> 
      struct enable_if : public enable_if_c<Cond::value, T> {};
    Ca me permet juste de choisir un type (if_) ou de vérifier un type (enable_if).

  6. #26
    Membre averti
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Points : 392
    Points
    392
    Par défaut
    ca me plaît comme idée (surtout que le paramètre unique touche rapidement ses limites...). Tu as plus d'infos dessus, ou du moins un lien qui explique le concept plus en détail?

  7. #27
    Membre averti
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Points : 392
    Points
    392
    Par défaut
    tiens, une "solution" qui me permettrait de contourner presque le problème des redifinitions des templates partiellement spécialisé serait de m'écrire une petite macro preprocesseur avec Boost.pp qui irait me fournir une spécialisation totale du constructeur pour chaque classe s'en servant. C'est lourd vu que ca mélange le Preprocesseur et le compilateur (et la metacompilation sur chacun des deux), et ca me plaît pas trop, mais l'idée y est...

  8. #28
    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
    Et pour les typelists ?
    Ca consiste à travailler sur une liste de types. Je te renvoie notamment vers Loki (http://loki-lib.sf.net/) et le bouquin associé (Modern C++ Design) pour en savoir plus.

  9. #29
    Membre averti
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Points : 392
    Points
    392
    Par défaut
    Je connais Loki, je me sers du SingletonHolder<> pour mes singletons.
    Vu que j'ai pas le bouquin d'Andrei Alexandrescu chez moi, tu peux m'en dire plus, notamment comment me servir du typelist dans mon exemple précis.

    Ce petit test ne compile pas, et j'ai un gros doute de comment me servir du typelist.
    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
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
     
    //some compiler tests
     
    #include <loki/typelist.h>
    #include <loki/typemanip.h>
     
    using namespace Loki;
    using namespace Loki::TL;
     
    struct Bar0
    {
    	Bar0(){}
    };
     
    struct Bar1
    {
    	float a;
    	Bar1(float p):a(p){}
    };
     
    struct Bar2 : Bar1
    {
    	int b;
    	Bar2(float p0, int p1):Bar1(p0),b(p1){}
    };
     
    //etc;
     
    template<class B, class Ty>
    struct Inter : B
    {
    	template<int length>
    	Inter(...);
    };
     
    template<class B, class Ty>
    Inter<B, Ty>::Inter<0>(Ty):B(){}
     
    template<class B, class Ty> template<>
    Inter<B, Ty>::Inter<1>(TypeAt<Ty, 0>::Result p):B(p){}
     
    template<class B, class Ty> template<>
    Inter<B, Ty>::Inter<2>(TypeAt<Ty, 0>::Result p0, TypeAt<Ty, 1>::Result p1):B(p0, p1){}
     
     
    struct Foo0 : Inter< Bar0, void>
    {
    	Foo0():Inter(){}
    };
     
    struct Foo1 : Inter< Bar1, float>
    {
    	Foo1(float i):Inter(i){}
    };
     
    typedef MakeTypelist<float, int>::Result b2tl;
     
    struct Foo2 : Inter< Bar2, b2tl>
    {
    	Foo2(float a, int b):Inter(a, b){}
    };

  10. #30
    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
    Je suppose que tu as fouillé toute la doc, les samples & compagnie ?

  11. #31
    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
    Points : 4 625
    Points
    4 625
    Par défaut
    Les typelists de Boost.MPL sont un peu un million de fois mieux que celles de Loki...
    Ça se manipule exactement comme les conteneurs standard, sauf que c'est des conteneurs de types et que ça travaille avec des méta-fonctions au lieu de fonctions.
    Boost ftw

  12. #32
    Membre averti
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Points : 392
    Points
    392
    Par défaut
    merci pour l'indice. D'ailleurs, j'ai trouvé Boost.Tuple qui correspond encore mieux à ce dont j'ai besoin. Et j'ai simplifié mon architecture, du coup j'ai pu déplacer ce problème dans une factory à part. Je posterai un peu de code demain.

Discussions similaires

  1. Réponses: 6
    Dernier message: 17/07/2012, 10h20
  2. Template spécialisation partielle
    Par saladin04 dans le forum Langage
    Réponses: 6
    Dernier message: 06/03/2011, 20h59
  3. [Template] spécialisation partielle des template
    Par vikki dans le forum Langage
    Réponses: 9
    Dernier message: 10/11/2008, 16h29
  4. Réponses: 4
    Dernier message: 15/10/2008, 09h33
  5. Réponses: 4
    Dernier message: 04/09/2008, 10h58

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