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 :

Revoila les template template !


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  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 Revoila les template template !
    Hello,

    J'ai l'occasion de me repencher sur les paramètres "template template" :

    J'aimerais faire un truc du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template <typename U, template <typename U> class T>
    struct RealType
    {
    	typedef typename T<U>::inner_index_type type;
    };
     
    template <typename U, typename T>
    struct RealType
    {
    	typedef T type;
    };
    Vous devez saisir l'idée.
    C'est assez basique, dans le domaine, mais je suis assez rouillé, et j'aimerais bien boucler ça avant ce soir.

    Vote aide serait la bienvenue pendant que je continue à chercher sur Google !

    (la recherche de chaines de groupes de mots sur le forum, ce n'est pas top)

  2. #2
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 760
    Par défaut
    Ceci ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template <typename U, typename T>
    struct RealType
    {
      typedef T type;
    };
     
    template <typename U, typename Z, template <typename> class T>
    struct RealType<U, T<Z> >
    {
      typedef typename T<U>::inner_index_type type;
    };

  3. #3
    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
    Merci !

    Ce qui me manquait, c'était ta ligne 8 : la configuration des paramètres template du trait.

    Du coup, j'ai trouvé plus simple, en éliminant le paramètre Z :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template <typename U, typename T>
    struct RealType<U, T>
    {
        typedef T type;
    };
    
    template <typename U, template <typename> class T>
    struct RealType<U, T<U>>
    {
        typedef typename T<U>::inner_index_type type;
    };
    Mais je ne comprend pas pourquoi le compilateur n'accepte pas ce qui est en rouge.

    Je vais essayer maintenant de faire en sorte que dans la seconde fonction, U ne puisse être qu'un type bien précis.

  4. #4
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    Ce qui est en rouge est une spécialisation, mais même si tu as définis le type de base, admettons :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template <typename U, typename T>
    struct RealType
    {
        typedef T type;
    };
    Est-ce que ça a un sens de spécialiser ? Et ça ne marcherait pas car la spécialisation ne spécialise rien, du coup il faut tout simplement l'enlever.

    EDIT : Comme j'ai compris le truc je pense qu'il faut faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // Type de base.
    template <Typename T>
    struct RealType
    {
    	typedef T type;
    };
     
    // Unwrap et selectionne le inner type.
    template <typename U, template <typename> class T>
    struct RealType<T<U> >
    {
    	typedef typename T<U>::inner_index_type type;
    };
    Pour rappel, tu définis d'abord un type de base et puis tu spécialises comme tu veux après, tu utilises alors la déclaration template pour déclarer ce que tu veux comme types et puis tu les "agences" dans la spécialisation pour que ça corresponde au nombre de template du type de base.

  5. #5
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 760
    Par défaut
    Je ne connais pas la finalité de RealType mais une approche différente est d'utiliser inner_index_type s'il existe dans T et dans le cas contraire utiliser T.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template <typename T, bool = has_inner_index_type<T>::value>
    struct RealType
    {
    	typedef T type;
    };
     
    template <typename T>
    struct RealType<T, true>
    {
    	typedef typename T::inner_index_type type;
    };
    Avec has_inner_index_type qui peut ressembler à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    template<typename T>
    class has_inner_index_type
    {
      typedef char yes_type;
      typedef struct { char a[2]; } no_type;
     
      template<typename U>
      static yes_type test(U*, typename U::inner_index_type* = 0);
      static no_type test(...);
     
    public:
      static const bool value = sizeof(test(static_cast<T*>(0))) == sizeof(yes_type);
    };
    À voir si c'est pertinent.

  6. #6
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    @jo_link_noir : C'est toujours intéressant d'apprendre des nouvelles techniques Par contre, il me semble que cette technique est principalement utilisée pour savoir si une classe hérite d'une autre – là où une spécialisation ne fonctionnera pas. Dans ce cas-ci je ne vois pas ce que ça ajoute à part une indirection (assez complexe en plus) au problème.

  7. #7
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 760
    Par défaut
    @Trademark: C'est aussi utilisé pour ça, la seul chose qui change est la fonction test. Comme il y a peu de changement, on peux facilement faire une macro pour générer la classe. Comme celle de Boost.MPL introspection.
    On peux aussi éliminer les indirection en utilisant typeof ou decltype.

    Juste pour exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    template <typename T>
    class RealType
    {
      template<typename U>
      static typename U::inner_index_type test(U*);
      static T test(...);
    public:
      using type = decltype(test(static_cast<T*>(0)));
    };
    J'ai proposé ça car RealType me donne l'impression de vouloir connaître le type interne d'une classe. Mais je voit 2 problèmes:
    - Il faut que la classe soit obligatoire un template avec 1 seul paramètre pour que la spécification utilise inner_index_type.
    - Même si la spécification passe, la classe ne contient pas forcement un type inner_index_type.

    Ne connaissant pas le contexte, je lâcher une solution alternative ou complémentaire au second problème ^^.

  8. #8
    Membre Expert
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Par défaut
    Citation Envoyé par jo_link_noir Voir le message
    Je ne connais pas la finalité de RealType mais une approche différente est d'utiliser inner_index_type s'il existe dans T et dans le cas contraire utiliser T.
    Comme les specialisations tempaltes donnent lieu a des substitutions, une simple couche de SFINAE suffit.

    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
     
    template<class T, class R=void>
    struct enable_if_type
    {
      typedef R type;
    };
     
    template<class T, class Enable=void>
    struct RealType
    {
      typedef T type;
    };
     
    template<class T>
    struct  RealType< T
                , typename enable_if_type<typename T::inner_type>::type
                >
    {
      typedef typename T::inner_type type;
    };
    beaucoup plus simple et moins gourmand en compile-time

Discussions similaires

  1. Problème avec template template template
    Par oodini dans le forum Langage
    Réponses: 6
    Dernier message: 23/11/2012, 14h40
  2. Réponses: 2
    Dernier message: 10/01/2009, 13h38
  3. Comment déployer les List Template sous WSS 3.0
    Par nassim12 dans le forum SharePoint
    Réponses: 2
    Dernier message: 23/06/2008, 12h36
  4. Ou mettre les fichiers templates / langues
    Par slasch dans le forum Zend Framework
    Réponses: 2
    Dernier message: 29/11/2007, 00h01

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