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 :

Paramètres de template


Sujet :

Langage C++

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2008
    Messages : 34
    Points : 26
    Points
    26
    Par défaut Paramètres de template
    Bonjour,
    J'ai une classe E qui dépend de plusieurs templates, supposons 4 :
    E<W, X, Y, Z>.

    Je sais à l'avance (au moment de la compilation) quelles sont les domaines
    sur lesquels les paramètres peuvent être définit : W peut être définit avec W1, ..., W4 ; X sur X1, X2 ; ...
    Idem pour les autres (W1, X1, ... sont des classes ou des structures).


    La problématique : Comment ne pas écrire les |W| * |X| * |Y| * |Z| différents cas possibles en dur dans le code, qui peut devenir rapidement un nombre élevé ?

    (J'ai besoin de lancer mes tests en parcourant tout ces paramètres, ils sont spécifiés à l'entré du programme : prog W2 X1 Y3 Z2)


    Y aurait t-il un moyen de préciser au compilateur que, W peut être définit sur W1, ... W4, X sur ... , lui faire compiler les différents cas possibles. Et à l’exécution aller dans le bon ?

    Ou bien au moins réduire les |W| * |X| * |Y| * |Z| cas à |W| + |X| + |Y| + |Z| cas.

    La question pourrait être reformuler en : comment transformer un string en paramètre de template, étant donné un domaine déjà définit et compilé au préalable ? (mais elle me semble sans solution)

  2. #2
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    739
    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 : 739
    Points : 3 627
    Points
    3 627
    Par défaut
    Bonsoir,

    polymorphisme ? Avec une batterie de test pour déduire chaque type.

    Sinon il faut faire une fonction qui déduis le type du premier paramètre. L'envoie à une fonction qui déduit le second, etc.
    Une horreur de ce type ^^
    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
     
    #include <iostream>
     
    struct A1 { void operator()(){ std::cout <<  "A1\n"; } };
    struct A2 { void operator()(){ std::cout <<  "A2\n"; } };
    struct B1 { void operator()(){ std::cout <<  "B1\n"; } };
    struct B2 { void operator()(){ std::cout <<  "B2\n"; } };
    struct B3 { void operator()(){ std::cout <<  "B3\n"; } };
     
    template<typename A, typename B>
    struct S
    {
      void operator()(){ A()(); B()(); }
    };
     
    template<typename A, typename B, typename Callback>
    void dispatch_run(Callback callback)
    {
      S<A,B>()();
      callback();
    }
     
    template<typename A, typename Callback>
    void dispatch_2(const char * s, Callback callback)
    {
      if (*s == '1') {
        dispatch_run<A, B1>(callback);
      }
      else if (*s == '2') {
        dispatch_run<A, B2>(callback);
      }
      else {
        dispatch_run<A, B3>(callback);
      }
    }
     
    template<typename Callback>
    void dispatch(const char * s, Callback callback)
    {
      if (*s == '1') {
        dispatch_2<A1>(s+1, callback);
      }
      else {
        dispatch_2<A2>(s+1, callback);
      }
    }
     
    struct Callback {
      const char * s;
      Callback(const char * str)
      : s(str)
      {}
     
      void operator()()
      { std::cout << s; }
    };
     
    int main()
    {
      dispatch("11", Callback("fin de 11\n"));
      dispatch("13", Callback("fin de 13\n"));
    }

  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Salut,

    A partir du moment où tu décides d'utiliser les templates, c'est que tu ne sais peut etre pas forcément quel type de données sera W, X, Y et Z, mais que tu sais par contre très bien comment tu vas utiliser ces données.

    Autrement dit, tu sais très bien quelle est l'interface publique des types qui seront utilisés

    Ou, plutôt, tu force ces quatre types à fournir une interface qui correspondra à tes besoins pour pouvoir les manipuler

    Autrement dit, tu peux très bien créer une fonction (je choisi une fontion pour la facilité, mais il en va de meme avec les classes et les structures ) template proche de
    t
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    emplate <typename W, typename X, typename Y, typename Z>
    void foo(W /*const & */ w, X /*const & */x, Y /*const &*/ y, Z /* const &*/ z){
        int i = w.foo() + x.bar() * y.truc() / z.brol(); 
    }
    sans que cela ne te pose de problème particulier.

    La seule chose, c'est que cela obligera l'utilisateur de cette fonction à s'assurer:
    1. que la classe utilisée comme étant W dispose bel et bien d'une fonction foo(),
    2. que celle utilisée comme étant X dispose bel et bien d'une fonction bar(),
    3. que celle utilisée comme étant Y dispose bel et bien d'une fonction truc() et
    4. que celle utilisée comme étant Z dispose bel et bien d'une fonction brol()
    Si ce n'est pas le cas, le compilateur t'enverra sur les roses en te disant que la classe qui ne satisfait pas ces exigences ne dispose pas de la fonction indiquée

    @ jo_link_noir Il ne peut être question de polymorphisme (au sens OO du terme) lorsque l'on travaille avec des template, pour la simple et bonne raison que les template sont gérées lors de la compilation
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Membre éclairé Avatar de metagoto
    Profil pro
    Hobbyist programmateur
    Inscrit en
    Juin 2009
    Messages
    646
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Hobbyist programmateur

    Informations forums :
    Inscription : Juin 2009
    Messages : 646
    Points : 845
    Points
    845
    Par défaut
    @matthieu637

    Le plus simple à mon avis est de générer les sources cpp de tests à l'aide d'un autre programme (probablement en python ou tout autre langage dynamique).

    La solution de jo_link_noir est astucieuse mais ne réduit que faiblement l'explosion combinatoire que tu cherches à éviter (si j'ai bien compris).

    Il y aurait peut être moyen d'arriver à quelque chose d’intellectuellement satisfaisant en pure c++ en s'appuyant sur des templates variadiques et une librairie de meta prog. Et/ou aussi abuser du préprocesseur (avec par exemple Boost.Preprocessor) mais je ne suis pas sûr que les efforts déployés en valent la peine.

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 12/10/2011, 18h08
  2. Renvoyer le type d'un paramètre de template
    Par mister3957 dans le forum Langage
    Réponses: 6
    Dernier message: 09/08/2008, 08h44
  3. [XSLT] template paramétré et XPATH
    Par 242 dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 30/11/2005, 09h39
  4. [XSLT][Saxon]passage de paramètres à une template
    Par RB Greg dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 12/05/2005, 16h29
  5. [XSL] Passage de paramètres à un template
    Par pantin dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 27/06/2003, 13h28

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