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

C++ Discussion :

Template specialization pour classes héritées


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2007
    Messages : 26
    Points : 17
    Points
    17
    Par défaut Template specialization pour classes héritées
    Bonjour,

    Pouvez-vous me dire si la spécialisation de templates peut m'aider pour mon cas ?

    J'ai une classe template dont je veux que le second argument soit obligatoirement dérivé d'une certaine classe, comment puis-je m'y prendre ?

    Ci dessous, un exemple.

    Merci et meilleures salutations,
    Gab

    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
    class A
    {
    };
     
    class B : public A
    {
    };
     
     
    // J'aimerais que le type T2 soit obligatoirement une classe dérivée de la classe A (la classe B par exemple)
    template<class T1, class T2>
    class MonTemplate
    {
    	//...
    };

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    Est-ce qu'un code comme ça fonctionnerait (je viens d'y penser sans jamais avoir essayé une telle chose)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class A {};
    class B : public A {};
    template< class T1, class T2 >
    class Template
    {
      A* monA;
      Template() {monA = new T2;};
    };
    A priori, tel que je l'imagine, si T2 n'est pas dérivé de A (ou directement A), la compilation devrait échouer.

    Sinon, as-tu vraiment besoin d'un template pour cela ?
    Ne peux-tu avoir uniquement un membre à initialiser ? Ce qui aurait un effet similaire à ce que j'imagine plus haut.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2007
    Messages : 26
    Points : 17
    Points
    17
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Est-ce qu'un code comme ça fonctionnerait (je viens d'y penser sans jamais avoir essayé une telle chose)
    A priori, tel que je l'imagine, si T2 n'est pas dérivé de A (ou directement A), la compilation devrait échouer.
    Ça pourrait marcher mais suivant le compilateur, peut-être que ça ne mercherait pas :-/

    Entre temps j'ai eu une autre idée, dis moi ce que tu en penses
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class B : public A
    {
        static void bidon() {}
    }
     
    template<class T1, class T2>
    class MonTemplate
    {
    	MonTemplate()
    	{
    		T2::bidon(); // plantage si non hérité de B
    	}
    };

    Citation Envoyé par Bousk Voir le message
    Sinon, as-tu vraiment besoin d'un template pour cela ?
    Ne peux-tu avoir uniquement un membre à initialiser ? Ce qui aurait un effet similaire à ce que j'imagine plus haut.
    En fait mon cas est beaucoup plus compliqué, j'ai une structure de classes assez grande, dont certains templates héritent d'autres et doivent en prendre d'autres en paramètres (sur fond de polymorphisme ^^)

    Merci

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par _56ka Voir le message
    Ça pourrait marcher mais suivant le compilateur, peut-être que ça ne mercherait pas :-/
    Pourquoi suivant le compilateur ? Je ne vois pas ce qu'il changerait là. Tout compilateur retourne une erreur si A* a = new B; si B n'est pas dérivé de A. Et inversement il acceptera une telle écriture.

    Citation Envoyé par _56ka Voir le message
    Entre temps j'ai eu une autre idée, dis moi ce que tu en penses
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class B : public A
    {
        static void bidon() {}
    }
     
    template<class T1, class T2>
    class MonTemplate
    {
    	MonTemplate()
    	{
    		T2::bidon(); // plantage si non hérité de B
    	}
    };
    En fait ça reprend exactement le même principe que j'imaginais^^
    Ou en tous cas dans mon esprit c'est similaire.
    Ca ne compile pas ? Il y a une erreur ?
    Le meilleur moyen de savoir ça reste de tenter de compiler.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Pour faire les choses proprement, je conseille la fonction is_base_of du C++11 (ou de boost.type_traits), qui permet de tester si une classe hérite d'une autre classe : http://en.cppreference.com/w/cpp/types/is_base_of ou http://www.boost.org/doc/libs/1_49_0...s_base_of.html

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2007
    Messages : 26
    Points : 17
    Points
    17
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Pourquoi suivant le compilateur ?
    Suivant la config du compilateur je voulais dire
    Il y a surement un paramètre trop permissif qui laisserait passer ça entre les gouttes ^^

    Citation Envoyé par Bousk Voir le message
    En fait ça reprend exactement le même principe que j'imaginais^^
    Ou en tous cas dans mon esprit c'est similaire.
    On est aliénés pareil, c'est un point positif

    Citation Envoyé par Bousk Voir le message
    Ca ne compile pas ? Il y a une erreur ?
    Le meilleur moyen de savoir ça reste de tenter de compiler.
    Alors je n'ai pas testé ta solution vu que j'ai eu une idée entre temps mais ma proposition fonctionne


    Citation Envoyé par gbdivers Voir le message
    Pour faire les choses proprement, je conseille la fonction is_base_of du C++11 (ou de boost.type_traits), qui permet de tester si une classe hérite d'une autre classe
    Merci pour ta contribution, je ne connaissais pas cette fonction ^^
    Par contre, le problème est que is_base_of génère une erreur à l'exécution et moi j'aimerais qu'elle se déclare à la compilation.

  7. #7
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Citation Envoyé par _56ka Voir le message
    Par contre, le problème est que is_base_of génère une erreur à l'exécution et moi j'aimerais qu'elle se déclare à la compilation.
    Non, c'est bien à la compilation
    Tu peux utilisé un static assert pour lancer une erreur si is_base_of est faux

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2007
    Messages : 26
    Points : 17
    Points
    17
    Par défaut
    Ah ce serait donc un template online ou un truc du genre ? cool
    C'est quoi un static assert exactement ? On peut les utiliser sans Boost ?

  9. #9
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Oui, avec C++11 (gcc > 4.3)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    // définition : static_assert(expression, string);
    #include <type_traits>
    static_assert(is_base_of<A, B>::value, "A not base of B");

  10. #10
    Membre actif Avatar de Rewpparo
    Homme Profil pro
    Amateur
    Inscrit en
    Décembre 2005
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Amateur

    Informations forums :
    Inscription : Décembre 2005
    Messages : 170
    Points : 281
    Points
    281
    Par défaut
    Citation Envoyé par _56ka Voir le message
    Entre temps j'ai eu une autre idée, dis moi ce que tu en penses
    Je l'utilise dans mon code actuel, j'ai aucun problème. Testé depuis deux mois GCC/MSVC

  11. #11
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Attention, selon ce que tu veux en faire, is_base_of peut retourner des faux positifs. Ainsi une classe de base privée retournera vrai.

    Mais bon, à la base, je n'aime pas trop imposer des contraintes si fortes sur mes templates...
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

Discussions similaires

  1. Templates et constructeurs de classe héritées
    Par Matthieu Brucher dans le forum Langage
    Réponses: 14
    Dernier message: 28/06/2014, 00h00
  2. Liens entre des classes héritées
    Par qwiqwi dans le forum C++
    Réponses: 12
    Dernier message: 09/02/2006, 15h36
  3. Réponses: 2
    Dernier message: 04/12/2005, 21h10
  4. [Template] methode template d'une classe pas template
    Par bigquick dans le forum Langage
    Réponses: 8
    Dernier message: 25/03/2005, 15h09

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