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 :

Relation d'ordre entre paramètres template.


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Par défaut Relation d'ordre entre paramètres template.
    Bonjour.

    J'ai créé une classe template avec deux paramètres T1 et T2 et j'aurais aimé garantir que sizeof(T2)>sizeof(T1). Malheureusement, je ne vois pas comment faire.

    En effet, j'ai tout d'abord essayé d'autiliser une sous class prenant un unsigned, mais je n'ai pas l'erreur à la compilation..
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    template <class T1, class T2>
    class A
    {
       private:
       template<unsigned int T>
       class B
       {
       };
       B<sizeof(T2)-sizeof(T1)> ex;
    };
    Je me trouve donc un peu bloqué... si quelqu'un avait une idée...

    merci

  2. #2
    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
    Par défaut
    Salut,
    Boost::enable_if:
    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
     
    #include <boost/utility/enable_if.hpp>
     
    template <class T1, class T2, class dummyT=typename boost::enable_if_c<(sizeof(T1)>sizeof(T2))>::type>
    struct A
    {
    };
     
    struct B1
    {
       unsigned char uc;
    };
    struct B2
    {
       unsigned char uc[2];
    };
     
    int main()
    {
       A<B2,B1> a1;
    //   A<B1,B2> a1; --> Error
       return 0;
    }
    Ou :
    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
    template<bool> struct enable_if_c;
    template<> struct enable_if_c<true>
    {
       typedef void type;
    };
     
    template <class T1, class T2, class dummyT=typename enable_if_c<(sizeof(T1)>sizeof(T2))>::type>
    struct A
    {
    };
     
    struct B1
    {
       unsigned char uc;
    };
    struct B2
    {
       unsigned char uc[2];
    };
     
    int main()
    {
       A<B2,B1> a1;
    //   A<B1,B2> a1;
       return 0;
    }
    Cependant, j'aurais tendance à dire que comparer la taille de 2 types n'est pertinent que dans un cadre de méta-prog si les 2 types sont liés entre eux (typiquement pour du sfinae).

  3. #3
    Membre Expert
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Cependant, j'aurais tendance à dire que comparer la taille de 2 types n'est pertinent que dans un cadre de méta-prog si les 2 types sont liés entre eux (typiquement pour du sfinae).
    Je dois reconnaitre que je n'utilise que des types numériques et leurs dérivés munis des opérations +, -, *, = et ==. le véritable test "mathématique" devrais porter sur l'inclusion de l'ensemble T1 dans l'ensemble T2, mais je me suis dit qu'une simple comparaisons de types serait sufisante... a moins qu tu voie autre chose....


    Sinon, vis à vis de ton exemple, il serait peut-être plus pertinent d'instancier A dans une classe contenante histoire d'éviter que l'utilisateur puisse spécifier le paramètre dummyT non ?

    merci

  4. #4
    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
    Par défaut
    Citation Envoyé par méphistopheles Voir le message
    Sinon, vis à vis de ton exemple, il serait peut-être plus pertinent d'instancier A dans une classe contenante histoire d'éviter que l'utilisateur puisse spécifier le paramètre dummyT non ?
    Effectivement. Instancier pose le problème d'ajouter un membre qui ne sert à rien. Vaut mieux utiliser un héritage privé (qui ne sert à rien) mais que le compilo optimise pour n'utiliser pas plus d'espace :
    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
     
    namespace details{ 
       struct dummy{};
    }
    template<bool,typename T> struct enable_if_c;
    template<typename T> struct enable_if_c<true,T>
    {
       typedef T type;
    };
     
    template <class T1, class T2>
    struct A : private enable_if_c<(sizeof(T1)>sizeof(T2)),details::dummy>::type
    {
    };
     
    struct B1
    {
       unsigned char uc;
    };
    struct B2
    {
       unsigned char uc[2];
    };
     
    int main()
    {
       A<B2,B1> a1;
       //A<B1,B2> a2; //--> Error
       return 0;
    }
    Citation Envoyé par méphistopheles Voir le message
    Je dois reconnaitre que je n'utilise que des types numériques et leurs dérivés munis des opérations +, -, *, = et ==. le véritable test "mathématique" devrais porter sur l'inclusion de l'ensemble T1 dans l'ensemble T2, mais je me suis dit qu'une simple comparaisons de types serait sufisante... a moins qu tu voie autre chose....
    En jouant avec std::limits : à l'exécution avec std::numeric_limits<>::min ou à la compilation avec l'enable_if et std::numeric_limits<>::digits10. Mais ça reste un peu de la bidouille.
    Mais ton problème ne peut-il se résoudre avec les Boost.numeric cast ?

  5. #5
    Membre Expert
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    template<bool,typename T> struct enable_if_c;
    template<typename T> struct enable_if_c<true,T>
    {
       typedef T type;
    };
    Heu... à quoi sert le type T ? il n'est pas essentiel si ? (à moins qu'on ne puisse hériter de void)...

    Citation Envoyé par 3DArchi Voir le message
    En jouant avec std::limits : à l'exécution avec std::numeric_limits<>::min ou à la compilation avec l'enable_if et std::numeric_limits<>::digits10. Mais ça reste un peu de la bidouille.
    Mais ton problème ne peut-il se résoudre avec les Boost.numeric cast ?
    A vrai dire, ce sont de types numériques mais certains étant définis par l'utilisateur , je ne suis pas sûr qu'ils soient standards donc boost risque de tomber sur un os...


    Je vais par contre rester sur la première solution.


    Merci beaucoup

  6. #6
    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
    Par défaut
    Citation Envoyé par méphistopheles Voir le message
    Heu... à quoi sert le type T ? il n'est pas essentiel si ? (à moins qu'on ne puisse hériter de void)...
    Effectivement, on ne peut hériter de void (ni de int, ni de char, etc.)

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

Discussions similaires

  1. Requête avec relation N-N (entre 3 tables)
    Par vynce dans le forum Langage SQL
    Réponses: 11
    Dernier message: 05/12/2005, 10h34
  2. relation maitre/esclave entre 2 BDD sur MySQL?
    Par root76 dans le forum SQL Procédural
    Réponses: 5
    Dernier message: 14/10/2005, 14h37
  3. Relation de dépendance entre résultats : une idée farfelue ?
    Par mdef dans le forum Langages de programmation
    Réponses: 4
    Dernier message: 18/07/2005, 02h04
  4. Mettre une relation 1,1 entre 2 tables
    Par borgfabr dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 11/05/2005, 17h20
  5. [XSLT] Différence entre apply-templates et call-template
    Par Cpt.FLAM dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 04/04/2005, 18h47

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