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 :

restriction sur une classe template


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2004
    Messages
    85
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 85
    Par défaut restriction sur une classe template
    voici le "toy" code suivant:
    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
     
     
    template< int n=2> 
    struct C{
     
    	int F () {return -n;}
    };
     
     
    template< int n=2> 
    struct A{
     
    	int F () {return n;}
    };
     
    template< int n=2> 
    struct B:public A<n>{
     
    	int F () {return n+1;}
    };
     
    template< class T> 
    struct H{
     
    	int h () { T a; return a.F();}
    };
     
     
    int main()
    {
    	H<A<> > u_a;
    	H<B<> > u_b;
    	H<C<> > u_c;   
     
    	int a = u_a.h();
    	int b = u_b.h();
    	int c = u_c.h();  
     
    	return 0;
    }
    je souhaiterai, si c'est possible, qu ' à la compiliation l'instantiation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    	H<C<> > u_c;   
    	int c = u_c.h();
    envoie une erreur.

    Le but est de restreindre la portée de l 'argument template de H pour seule les classes dérivées de A soient permises et cela sans toucher aux classes A,B ou C.

    Merci encore
    Mathieu

  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
    Je te conseille de regarder du côté de boost.type_traits, en particulier :
    http://www.boost.org/doc/libs/1_40_0...s_base_of.html
    Il te suffit d'utiliser is_base_of<A, ton_paramètre_template>::value dans un endroit qui provoque une erreur de compilation si ça évalue à false. Typiquement : char foo[is_base_of<A, T>::value ? 1 : -1];
    Ou plus simple, un BOOST_STATIC_ASSERT ou similaire.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2004
    Messages
    85
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 85
    Par défaut
    Je viens de regarder ta proposition.
    Il n'y a donc pas une synthaxe c++ qui empèche certaines instantiations.
    Il faut avoir recours à Boosts ,que je ne peux pas insérer dans ma librairie de travail

    Au secours!

  4. #4
    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
    Sinon, tu as des petits hacks si tu veux détecter ce genre de choses à la compilation.

    Je verrais bien, par exemple, quelque chose de ce genre (à vérifier, mais l'idée est là) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    struct true_type { char c; }
    struct false_type { };
     
    true_type f(const A& a) { return true_type(); }
     
    template <typename t>
    false_type f(const T& t) { return false_type(); }
     
    // ... dans H< T >
    char foo[sizeof(f(T()) != sizeof(false_type) ? 1 : -1];
    Quelque chose de ce genre en tout cas. Je devrais pouvoir mieux t'éclairer d'ici 2 ou 3 cafés...

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2004
    Messages
    85
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 85
    Par défaut
    ok j attends l effet de la caféine alors. Si tu veux aller plus vite, prends du guarana ou emphetamine, c est assez efficace aussi

  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
    Un Kfé bien serré :
    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
    template< int n=2> 
    struct C{
     
    	int F () {return -n;}
    };
     
     
    template< int n=2> 
    struct A{
    	int F () {return n;}
    };
     
    template< int n=2> 
    struct B:public A<n>{
     
    	int F () {return n+1;}
    };
     
     
    struct true_type { char c; };
    struct false_type {true_type t[2]; };// je préfère faire dépendre de true_type pour être sur qu'ils ont vraiment une taille différente
     
    template<int n> true_type f_check(A<n>const&);
    false_type f_check(...);
     
    template<bool ,class> struct enable_if;
    template<class T> struct enable_if<true,T>{typedef T type;};
     
    template< class T> 
    struct H{
       typedef typename enable_if<(sizeof(f_check(T()))== sizeof(true_type)),T>::type check_type;
    	int h () {
          T a; return a.F();
       }
    };
     
    int main()
    {
    	H<A<> > u_a;
    	H<B<> > u_b;
    	H<C<> > u_c;   
       u_a.h();
       u_b.h();
       u_c.h();
     
    	return 0;
    }
    Il existe __is_base_of( base , derived) qui est du Visual spécifique mais que je ne vois pas trop comment appliquer avec une classe de base template sans connaître les paramètres génériques utilisés pour l'héritage.

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    La même que 3Darchi pour moi, le tout bien encapsulé dans une structure, histoire de cacher les détails d'implémentation.
    Y'a juste le coup du T(), si le type n'est pas default-constructible c'est fichu, donc je préfère passer par une fonction helper (juste la signature, on se fiche de la définition ;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    T makeT(); // pas la peine de la définir puisqu'elle sera juste évalué par sizeof().

  8. #8
    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 Goten Voir le message
    Y'a juste le coup du T(), si le type n'est pas default-constructible c'est fichu, donc je préfère passer par une fonction helper (juste la signature, on se fiche de la définition ;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    T makeT(); // pas la peine de la définir puisqu'elle sera juste évalué par sizeof().
    bien vu

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 12/11/2013, 13h22
  2. Fuite mémoire sur une classe template.
    Par robinsondesbois dans le forum Langage
    Réponses: 17
    Dernier message: 11/07/2013, 16h38
  3. Restriction sur une fonction template
    Par Arzar dans le forum Langage
    Réponses: 12
    Dernier message: 02/10/2009, 00h06
  4. Question sur une classe <template>
    Par Pingva dans le forum C++
    Réponses: 1
    Dernier message: 26/01/2007, 17h16
  5. [MFC] Problème pointeur sur une classe
    Par mick74 dans le forum MFC
    Réponses: 7
    Dernier message: 14/04/2004, 14h17

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