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 :

membres en fonction d'un template


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    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
    Par défaut membres en fonction d'un template
    J'ai encore une autre question sur les templates qui me travaille depuis un certain temps: est-ce qu'il est possible de faire un "branchement" selon un paramètre de template ?

    Par exemple, du genre suivant: (code qui ne compilera pas)
    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
     
    template<typename _T, int _sizeT>
    struct vec_proto
    {
      union
      {
         _T a[_sizeT];
        struct
        {
           _T x;
    ##if(_sizeT >= 2)
           _T y;
    ##if(_sizeT >= 3)
           _T z;
    ##if(_sizeT >= 4)
           _T w;
    ##if(_sizeT > 4)
    #pragma error;
    ##endif
    ##endif
    ##endif
    ##endif
        };
      };
    };

  2. #2
    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
    Salut,

    Bon déjà là ça rentre dans le cadre de la métaprogrammation (pour des solutions "automatisées").
    Tu trouveras de quoi te satisfaire sur le sujet (niveau lecture + outils) dans l'article de Laurent (http://loulou.developpez.com/tutoriels/cpp/metaprog/) et dans Boost.MPL (http://www.boost.org/doc/libs/1_35_0...doc/index.html).

    Toutefois, la solution la plus facile à mettre en place dans ton cas, c'est de spécialiser selon la valeur de sizeT.

    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
     
    template<typename _T, int _sizeT>
    struct vec_proto
    {
      union
      {
         _T a[_sizeT];
           struct 
           {
              _T x;
           };
       };
    };
     
    template <typename _T>
    struct vec_proto<_T, 2>
    {
       union
       {
          _T a[2];
          struct
          {
             _T x;
             _T y;
          };
       };
    };
     
    // etc...
    Et pour générer les spécialisations automatiquement, regarde du côté de Boost.Preprocessor (http://www.boost.org/doc/libs/1_35_0...doc/index.html).

  3. #3
    Membre éclairé
    Inscrit en
    Mai 2005
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 73
    Par défaut
    Je connais assez mal la méta-programmation, mais ton problème m'a donné envie de m'amuser un peu, voilà ce qui en est ressorti :

    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
    //Permet de créer une structure contenant N attributs nommés x1..xN
     
    template<int a, int b>
    struct sub
    {
        static const int res = a - b;
    };
     
    template<typename T, int N>
    struct attr
    {
    };
     
    #define ATTR(n)                                     \
     template<typename T>                               \
     struct attr<T, n> : public attr<T, sub<n, 1>::res> \
     {                                                  \
         T x##n;                                        \
     }
     
    ATTR(1);
    ATTR(2);
    ATTR(3);
    ATTR(4);
     
    int main()
    {
        attr<int, 1> a;
     
        a.x1;
        //a.x2 --> erreur de compilation
     
        attr<int, 2> b;
     
        b.x1;
        b.x2; // --> ok
     
        attr<int, 5> notok; // malheureusement, cela passe à la compil
     
        //notok.x1; --> si on essaye d'atteindre un attribut, erreur de compil
     
        return 0;
    }
    Je n'ai pas mis le tableau, mais je ne pense que cela pose trop de problèmes.

  4. #4
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Tu te complique la vie avec ta structure sub.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    //...
    struct attr<T, n> : public attr<T,n-1>		    \
    //....
    passe tout aussi bien.

    Edit:
    Ce code empèche att<int,5> de compiler
    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
     
    template<typename T, int N> struct attr;
    template <typename T> struct attr<T,0>{};
     
    #define ATTR(n)                                     \
     template<typename T>                               \
     struct attr<T, n> : public attr<T,n-1>		    \
     {                                                  \
         T x##n;                                        \
     }
     
    ATTR(1);
    ATTR(2);
    ATTR(3);
    ATTR(4);
     
    int main()
    {
        attr<int, 1> a;
     
        a.x1;
        //a.x2 --> erreur de compilation
     
        attr<int, 2> b;
     
        b.x1;
        b.x2; // --> ok
     
        attr<int, 5> notok; //passe plus
     
        return 0;
    }
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  5. #5
    Membre éclairé
    Inscrit en
    Mai 2005
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 73
    Par défaut
    Citation Envoyé par Davidbrcz Voir le message
    Tu te complique la vie avec ta structure sub.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    //...
    struct attr<T, n> : public attr<T,n-1>		    \
    //....
    passe tout aussi bien.
    Tout à fait, c'est une complication totalement inutile ! Je l'ai mise en oeuvre en me disant que le préprocesseur ne ferait pas le calcul et remplaçerait le code par attr<T, 1 - 1> au lieu de attr<T, 0>...mais ça n'a aucune raison de gêner le compilo ! J'ai le cerveau qui tourne au ralenti...

  6. #6
    Membre éclairé
    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
    Par défaut
    j'ai l'impression que ce que je veux générer pourrait se faire via BOOST_PP_ARRAY_DATA(a), mais je n'ai pas vraiment compris l'exmple. (Bon,il fait tard après une semaine lourde en boulot, donc...)

    edit: merci pour les idées, j'ai écrit un petit bout de code:
    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
    template<typename T>
    struct math
    {
    	class vec2;
    	class vec3;
    	class vec4;
    };
     
    template<typename T, int sizeT> 
    struct t_vec;
     
     
    template<typename T>struct t_vec<T, 2>{	T x; T y;	};
    template<typename T>struct t_vec<T, 3>{	T x; T y; T z;	};
    template<typename T>struct t_vec<T, 4>{	T x; T y; T z; T w;	};
     
    template<typename T, int sizeT> union tunion
    {
    	T a[sizeT];
    	t_vec<T, sizeT> v;
    };
     
    template<typename T>
    struct math<T>::vec2
    {
    	tunion<T, 2> u;
    };
     
    template<typename T>
    struct math<T>::vec3
    {
    	tunion<T, 3> u;
    };
     
    template<typename T>
    struct math<T>::vec4
    {
    	tunion<T, 4> u;
    };
    pour l'instance du tout:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    math<float>::vec2 fv2;
    	fv2.u.v.x = 1.0f;
    	fv2.u.v.y = 2.0f;
    le poblème, c'est que ce u.v.x ... c'est un peu lourdingue. Il y a mieux, je suppose. Des idées?

  7. #7
    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
    Pour empêcher d'instancier à plus de 4 et moins de 1, on peut utiliser un static assert, ceux de boost pour le moment par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #define ATTR(n)                                     \
     template<typename T>                               \
     struct attr<T, n> : public attr<T, n-1> \
     {                      
         BOOST_STATIC_ASSERT(n > 0 && n < 5)       \
         T x##n;                                                   \
     }

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

Discussions similaires

  1. fonction membre depuis fonction anonyme
    Par PoZZyX dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 09/06/2010, 17h30
  2. Appel de fonction problème class/template
    Par Niko_de_bordo dans le forum Langage
    Réponses: 3
    Dernier message: 15/04/2010, 00h48
  3. [2K8] Membres Calculés - Fonction AVG
    Par Mourad69 dans le forum SSAS
    Réponses: 1
    Dernier message: 18/08/2009, 11h13
  4. Réponses: 0
    Dernier message: 25/07/2007, 14h47
  5. Réponses: 11
    Dernier message: 18/02/2007, 15h37

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