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 :

Faire un using pour tout les templates d'un même type (ou d'une même famille de types) d'un pack de templates?


Sujet :

Langage C++

  1. #1
    Invité
    Invité(e)
    Par défaut Faire un using pour tout les templates d'un même type (ou d'une même famille de types) d'un pack de templates?
    Salut.
    J'ai essayé plusieurs autres techniques mais l'héritage ne suffit plus à mes besoin, et je ne sais pas si c'est possible de faire cela avec un template parameter pack.

    Ma question peut ne pas paraître très claire, ce que je cherche à faire c'est ceci, par exemple j'ai cette structure de ce type la.

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    MyStruct<int, float, double, int, long> stuct1.

    Et ce que je voudrais c'est arriver à une structure de ce type là :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    MyStruct<int, int> struct2;

    En faisant ça avec un template parameter pack pour les templates de struc1t, pour récupérer un using sur les templates de struct2.

    Ce qui donnerait quelque chose comme, au niveau utilisation :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    get_identical_params<int, float, double, int, long>::type

    Ou type correspond à MyStruct<int, int>

    Voila merci d'avance pour votre aide.

  2. #2
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    C'est de la méta-programmation template qu'il faut faire, un exemple :
    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
     
    template<class...>
    struct MyStruct;
     
    template<class T, class... Arg>
    struct get_identical_params
        : get_impl<T,MyStruct<T>,MyStruct<Arg...>>
    { };
     
    template<class,class,class>
    struct get_impl;
     
    template<class T, class... ArgT, class... ArgU>
    struct get_impl<T,MyStruct<ArgT...>,MyStruct<T,ArgU...>>
        : get_impl<T,MyStruct<ArgT...,T>,ArgU...>
    { };
     
    template<class T, class U, class... ArgT, class... ArgU>
    struct get_impl<T,MyStruct<ArgT...>,MyStruct<U,ArgU...>>
        : get_impl<T,MyStruct<ArgT...>,ArgU...>
    { };
     
    template<class T, class... Arg>
    struct get_impl<T,MyStruct<Arg...>,MyStruct<>>
    { using type =MyStruct<Arg...>; };
    Code non testé, mais l'idée est là.

    Edit: Voir correction et explication détaillé de Winjerome

  3. #3
    Invité
    Invité(e)
    Par défaut
    J'ai un peu de mal avec la méta-programmation template, je ne sais pas comment je pourrai m'exercer, avec l'option -E qui permet de voir le code généré peut être que là je comprendrais mieux, car à vu d’œil là je ne sais pas du tout ce que va générer ce petit bout de code.

  4. #4
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Petites rectifications pour que ce soit fonctionnel :
    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
    template<class...>
    struct MyStruct;
     
    template<class,class,class>
    struct get_impl;
     
    // 1
    template<class T, class U, class... ArgT, class... ArgU>
    struct get_impl<T, MyStruct<ArgT...>, MyStruct<U,ArgU...>>
        : get_impl<T, MyStruct<ArgT...>, MyStruct<ArgU...>>
    { };
     
    // 2
    template<class T, class... ArgT, class... ArgU>
    struct get_impl<T,MyStruct<ArgT...>, MyStruct<T,ArgU...>>
        : get_impl<T, MyStruct<ArgT...,T>, MyStruct<ArgU...>>
    { };
     
    // 3
    template<class T, class... Arg>
    struct get_impl<T, MyStruct<Arg...>, MyStruct<>>
    { using type = MyStruct<Arg...>; };
     
    // 4
    template<class T, class... Arg>
    struct get_identical_params
        : get_impl<T, MyStruct<T>, MyStruct<Arg...>>
    { };
    Lors de l'appel à get_identical_params<int, float, double, int, long>::type, notre structure get_identical_params héritera de : get_impl<T,MyStruct<T>,MyStruct<Arg...>> avec ici :
    T = int ;
    Arg... = float, double, int, long
    Le premier type de Arg... étant ici float, différent du premier T = int on va passer par (1) : qui déroulé donne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    struct get_impl<int,MyStruct<int>, MyStruct<float,double,int,long>>
        : get_impl<int,MyStruct<int>, MyStruct<double,int,long>>
    Tu remarqueras que l'on ne stocke pas le type float dans le deuxième paramètre template étant donné qu'il n'est pas identique au T = int, Sinon on serait passé par l'étape (2)*.
    Identiquement pour le "nouveau" double qui n'est pas identique à int, on repasse par (1) pour l'éliminer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    struct get_impl<int,MyStruct<int>, MyStruct<double,int,long>>
        : get_impl<int,MyStruct<int>, MyStruct<int,long>>
    Arrivant à un int, on passe alors par l'étape (2) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    struct get_impl<int,MyStruct<int>, MyStruct<int,long>>
        : get_impl<int, MyStruct<int,int>, MyStruct<long>>
    Tu peux voir que l'on a ajouté le deuxième int dans le deuxième paramètre template, et il ne reste plus que le long dans le troisième paramètre template, qui sera éliminé de la même façon que précédemment en passant par le (1), suite à quoi notre le troisième paramètre template sera vide, et l'on arrivera au (3) pour terminer la récursion et utiliser nos deux int stockés : using type = MyStruct<int, int>;.

    Pour résumer :
    On part avec tous nos types dans la partie droite (3e paramètre template de get_impl), puis en passant récursivement dans les parties (1) / (2) :

    (1) lorsque le type est différent : on le supprime du troisième paramètre template ;
    (2) lorsque c'est le même type : on le supprime du troisième paramètre template, et l'ajoute dans le deuxième.
    Finalement, lorsque tous les types du troisième paramètre template ont été parcourus et supprimés, et nos types identiques stockés dans le deuxième, il nous reste à définir notre type avec (3)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    struct get_identical_params
        : get_impl<int,MyStruct<int>,MyStruct<float, long, int, double>> // 4
            : get_impl<int,MyStruct<int>, MyStruct<double,int,long>>     // 1
                : get_impl<int,MyStruct<int>, MyStruct<int,long>>        // 1
                    : get_impl<int,MyStruct<int,int>, MyStruct<long>>    // 2
                        : get_impl<int,MyStruct<int,int>, MyStruct<>>    // 1
                            using type = MyStruct<int,int>;              // 3
    * À cause du T commun, alors ajouté au deuxième paramètre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template<class T, class... ArgT, class... ArgU>
    struct get_impl<T,MyStruct<ArgT...>, MyStruct<T,ArgU...>>
        : get_impl<T, MyStruct<ArgT...,T>, MyStruct<ArgU...>>
    { };
    Dernière modification par Invité ; 08/02/2015 à 00h23.

Discussions similaires

  1. Réponses: 2
    Dernier message: 09/06/2015, 18h57
  2. Réponses: 2
    Dernier message: 12/09/2014, 21h31
  3. [MySQL] requete pour faire un select dans toutes les tables pour trouver le titre
    Par japhettchabao dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 12/09/2014, 20h02
  4. Réponses: 2
    Dernier message: 07/09/2011, 11h00
  5. Réponses: 6
    Dernier message: 06/10/2004, 10h41

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