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 :

Restreindre une instanciation de template à certains types


Sujet :

Langage C++

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut Restreindre une instanciation de template à certains types
    Hello,

    Soit un template :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template <typename T>
    class MyClass
    {
        ...
    };
    La façon habituelle de restreindre l'instanciation à un nombre données de types (ici, A et B) et de ne pas fournir d'implémentation générique, et de spécialiser pour chaque classe privilégiée :

    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
    template<>
    class MyClass;
     
    template<>
    class MyClass<A>
    {
        ...
    };
     
     
    template<>
    class MyClass<B>
    {
        ...
    };
    Si le code est commun aux deux spécialisations (nonobstant le type fourni en argument template), on se retrouve avec de la duplication de code. Il y a-t-il moyen de faire autrement ?

    J'essaye de bidouiller avec C++11, mais je l'impression que ça en va pas être très propre...

  2. #2
    Membre expérimenté Avatar de Nogane
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 241
    Par défaut
    Bonjour,
    Je vois 2 méthodes:
    - Mettre les définitions des méthodes dans le cpp, et instancier explicitement MyClass<A> et MyClass<B>.
    - Utiliser static_assert avec is_same:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static_assert(std::is_same<T, A>::value || std::is_same<T, B>::value, "Can't instanciate this type");

  3. #3
    Inactif  


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

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Bonjour

    Je dirais toujours avec la règle "ajouter une indirection", càd ici une fonction "is_instanciable"

    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
    template<class T>
    class is_instanciable {};
     
    template<>
    class is_instanciable<A>
    {
        typedef A type;
    };
     
    template<>
    class is_instanciable<B>
    {
        typedef B type;
    };
     
    template<class T>
    class MyClass {
        typedef typename is_instanciable<T>::type type;
    };
    C'est méthode mode "brute" n° 1, regarde du côté de boost mpl et type traits, il y a des exemples de ce type

    EDIT : petit correction dans le code, je n'utilisais pas le is_instanciable<T>

  4. #4
    Inactif  


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

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Citation Envoyé par Nogane Voir le message
    Bonjour,
    Je vois 2 méthodes:
    - Mettre les définitions des méthodes dans le cpp, et instancier explicitement MyClass<A> et MyClass<B>.
    - Utiliser static_assert avec is_same:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static_assert(std::is_same<T, A>::value || std::is_same<T, B>::value, "Can't instanciate this type");
    C'est effectivement possible. Par contre, on perd la possibilité d'ajouter à la volé d'autres classes (non respect du OCP) : si on veut ajouter une 3ème classe, il faut modifier du code existant.
    D'où l'intérêt d'utiliser uniquement la spécialisation, il suffit de fournir une nouvelle spécialisation sans toucher au code existant et le compilation fera le boulot lors de l'instanciation des templates

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Voici ce que j'ai fait :

    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
    template <class T>
    class HasAccess
    {
    	typedef bool value_type;
    	static const value_type value = false;
    };
     
    template <>
    class HasAccess<A>
    {
    	typedef bool value_type;
    	static const value_type value = true;
    };
     
    template <class T, bool hasAccess = HasAccess<T>::value>
    class MyClass;
     
    template <class T>
    class MyClass<T, true>;
    {
        ...
    };

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Bon, finalement, vu que j'avais d'autres contraintes qui me permettaient d'empêcher l'instanciation, je n'ai pas eu besoin d'avoir recours ces techniques.

    Cela servira peut-être à d'autres.

    Merci !

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

Discussions similaires

  1. Réponses: 12
    Dernier message: 31/12/2011, 09h34
  2. [VB6]N'afficher que certain type de fichier dans une FileListBox
    Par Misha dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 03/11/2008, 18h34
  3. Réponses: 2
    Dernier message: 02/10/2008, 16h37
  4. Réponses: 3
    Dernier message: 13/02/2008, 22h32
  5. Passer une fonction en template et instanciation
    Par Loïc B. dans le forum Langage
    Réponses: 7
    Dernier message: 07/11/2007, 16h30

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