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 :

Technique de la Metaprogrammation


Sujet :

Langage C++

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    505
    Détails du profil
    Informations personnelles :
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Août 2008
    Messages : 505
    Points : 712
    Points
    712
    Par défaut Technique de la Metaprogrammation
    Bonjour,

    J'essaie de comprendre quelques notions "avancées" du c++, et je viens de lire l'article métaprogrammation. Il est très bien écrit, mais le concept m'échappe.
    De ce que je comprends, on optimise des fonctions à la compilation en utilisant des ruses de sioux pour les transcrire sous forme de template.
    Bon, mais du coup, je ne comprends pas pourquoi la même chose ne peut pas être faite par le compilateur, par exemple en lui spécifiant que la fonction pourrait être précalculée. Si l'optimisation est faisable quand c'est un template, il n'y a pas de raison qu'elle ne soit pas faisable quand c'est une fonction. Peut-être faut-il ajouter des mot-clés, mais en l'état, ça me parait assez inélégant de devoir potentiellement écrire la même chose selon deux syntaxes différentes pour des questions d'optimisation.

    Qu'en pensez-vous ?

  2. #2
    Membre expérimenté 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
    Points : 1 396
    Points
    1 396
    Par défaut
    Salut,

    la metaprogrammation est très intéressante, elle permet d'optimiser ton code dès la compilation.

    Admettons une fonction d'addition qui ajoute un nombre fixe à un autre nombre. En "simple" programmation, tu pourrais faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    void addition(const int& element_fixe, int& element_variable)
    { element_variable += element_fixe ; }
    Le compilateur ne pourra jamais deviner que la valeur de element_fixe ne changera jamais dans le code. Dans ce cas, on préfère écrire ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    template <int element_fixe>
    void addition(int& element_variable)
    { element_variable += element_fixe ; }
    A la compilation la première fonction ne "changera pas" tandis que la deuxième deviendra (dans le cas où element_fixe = 2) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    void addition( int& element_variable )
    { element_variable += 2 ; }
    C'est évidement plus efficace que la première solution. Personnellement, ça ne fait que quelques semaines que j'utilise à fond toutes ces techniques (et je n'en suis qu'au début), et je me rend bien compte que différencier les variables qui seront forcément connues à la compilation et les autres est une forme d'optimisation importante.

    En dehors de cet exemple simplet, il y a des bibliothèques spécialisées qui te permettent de faire des choses beaucoup plus puissantes comme Boost::mpl (mpl = metaprogrammation language).

    Si ça t'intéresse, j'ai été confronté à un problème de ce domaine (alors que je n'y connaissais rien du tout) : http://www.developpez.net/forums/d11...late-non-type/

    Je devais passer en paramètre template un nombre indéfini d'arguments template à la fonction. Tu pourras voir le développement, et peut-être comprendre les enjeux d'une telle programmation.

    En tout cas même si tu n'en vois pas l'avantage maintenant, ne néglige jamais ce type de programmation.

    En outre, ce n'est pas écrire "deux fois la même chose selon deux syntaxes différentes" mais plutôt l'écrire une fois correctement !

    En tout cas bonne chance et le mieux pour comprendre tout ça, c'est de refaire ou te lancer dans un projet en te demandant ce qui peut être optimiser à la compilation. Et si tu cales, demander sur un forum les techniques potentielles pour résoudre tel ou tel type de problème.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    505
    Détails du profil
    Informations personnelles :
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Août 2008
    Messages : 505
    Points : 712
    Points
    712
    Par défaut
    Merci d'abord pour cette réponse.
    Je veux préciser que je ne méprise pas une technique ou quoi que ce soit, surtout avec mon niveau de compétence. Je cherche juste à comprendre. Ton exemple sur l'addition me semble intéressant. En fait, il y aurait bien moyen d'expliquer au compilateur des qu'il doit optimiser la fonction addition.
    Il y aurait même plusieurs solutions que l'on pourrait envisager.

    1) tout d'abord, on pourrait penser que le compilo comprendrait que le const impose que le paramètre est constant. Mais bon, l'exemple est peut-être un peut trop particulier.

    2) plutôt que d'imposer une deuxième syntaxe pas très jolie, pourquoi on a pas un élément du style inline, qui permettrait de dire au compilo: attention, optimise-moi ça, les paramètres suivants (a,b,c,..) vont être fixés ? Ca serait quand même plus joli non ?

    Du coup, la question que je me pose est la suivante: doit-on considérer que cette usage qui a une dimension historique est fixé pour toujours, ou bien est-ce qu'il y a un mouvement vers une simplification de cette métaprogrammation ?

  4. #4
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Une manière de penser à la métaprogrammation qui m'aide a expliquer le fond du concept à des collegues qui s'y mettent (par nécessité sur certains projets) est la suivante :


    En métaprogrammation, on manipule des types. Les valeurs sont des types.

    Il n'y a pas (encore) de type de types (ce qu'on appelle des "concepts"). template< typename T >, T a une valeur qui est un type, qui peut être n'importe quoi.


    Qu'est-ce que ça veut dire? Ca veut dire qu'au final tu manipule un ou plusieurs types, tu le passe dans des moulinettes qui au finalent vont donner un autre type, ou même plusieurs parfois, et que tout ça se passe à la compilation avant que le code final soit généré.

    Du coup, ça reviens plus ou moins à "scripter" le compilateur, en lui disant comment générer un type ou comment choisir un type optimal parmis plusieurs ou autres manipulations dans le genre.


    Et il faut faire une distinction entre métaprogrammation et template. Les templates permettent la meta programmation mais c'est plus ou moins une propriété découverte. A l'origine ça permet de générer du code optimisé à partir d'u schema, le template, qu'on reproduit mais en prennant en compte le context dans lequel il est utilisé (le point d'instanciation).
    La méta programmation est possible par les templates, mais quand tu fais une fonction template simple, ce n'est pas forcément de la métaprogrammation.

    Tu as des exemple plus clair avec les tuples ou boost::mpl : tu fais une liste de types (qui n'existe donc que pendant la compilation) que tu peux passer dans des autres types qui sont construit de manière à "trier" la liste de type pour générer un seul type final qui est celui qui est au top de la liste triéer. Une fois fait, le compilo se retrouve avec un seul type et va l'utiliser là ou tout ce que je viens de décrire à été instancié.

    Tout cela sous entends qu'on ne peut pas manipuler ces types lors de la compilatino sans utiliser un language différent du code qu'on utilse pour le runtime. Déjà, le code non template est optimisé à la compilation, tout ce qui peut être viré est viré, tout ce qui peut être executé à la compilatino l'est, mais ce n'est pas tout le code.
    Le code template est implicitement inliné la plupart du temps donc il profite d'optimizations relative au context où il est appelé.

    Les templates sont un language a part justement, qui décrit du code mais qui du coup est résolu à la compilation, donc forcément tout le code template ne se retrouvera pas dans le code final de l'executable. Les templates étant essentiellement des instructions destinée au compilateur pour générer du code, on peut lui faire faire tout et n'importe quoi quand il executera ce code template à la compilation.



  5. #5
    Membre éclairé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 426
    Points : 827
    Points
    827
    Par défaut
    Salut Thierry,

    Citation Envoyé par thierry.chich Voir le message
    on pourrait penser que le compilo comprendrait que le const impose que le paramètre est constant.
    Pas exactement, dans ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    void addition(const int& element_fixe, int& element_variable)
    { element_variable += element_fixe ; }
    le 'const' signifie que :
    1)soit 'element_fixe' est réellement une constante
    2)soit 'element_fixe' est une variable, mais le mot 'const' garantit qu'elle ne sera pas modifiée par la fonction 'addition'

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    505
    Détails du profil
    Informations personnelles :
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Août 2008
    Messages : 505
    Points : 712
    Points
    712
    Par défaut
    Citation Envoyé par bertry Voir le message
    Salut Thierry,



    Pas exactement, dans ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    void addition(const int& element_fixe, int& element_variable)
    { element_variable += element_fixe ; }
    le 'const' signifie que :
    1)soit 'element_fixe' est réellement une constante
    2)soit 'element_fixe' est une variable, mais le mot 'const' garantit qu'elle ne sera pas modifiée par la fonction 'addition'
    Effectivement. Des fois, c'est subtil

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    505
    Détails du profil
    Informations personnelles :
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Août 2008
    Messages : 505
    Points : 712
    Points
    712
    Par défaut
    Merci Klaim pour ta longue réponse. Je comprends bien l'esprit, ton explication est éclairante.
    Toutefois, sur la forme, je trouve un peu choquant les contorsions syntaxiques que cela impose.

    Mais bon, je vais suivre tes conseils et regarder du coté de tuple pour voir si j'arrive à me sortir de l'idée qu'on aurait pu faire plus proprement en écrivant des fonctions simple, mais en indiquant des choses au compilo au moyen de mots clés.

  8. #8
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Toutefois, sur la forme, je trouve un peu choquant les contorsions syntaxiques que cela impose.
    C'est tout a fait normal parceque les templates n'étaient pas prévu pour la métaprog au départ, il a été découvert après inclusion dans le standard qu'en fait c'était turing complete...


    D'ailleurs, un mec un peu connu a fait un parallèle assez clair avec Haskel, pour montrer que ça fait a peu près la même chose qu'Haskell mais avec une syntaxe pas top. Faut que je retrouve le liens... ya une présentation dans les video de BoostCon aussi.

  9. #9
    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
    D'ailleurs, un mec un peu connu a fait un parallèle assez clair avec Haskel
    Bartosz Milewski ? : http://bartoszmilewski.wordpress.com/

  10. #10
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Exact, merci!

  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
    A noter que pour les exemples servant à calculer des valeurs (et pas des types) à la compilation, une syntaxe bien plus simple a finalement été mise en œuvre en C++11. Recherche constexpr pour en savoir plus.
    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.

  12. #12
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    505
    Détails du profil
    Informations personnelles :
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Août 2008
    Messages : 505
    Points : 712
    Points
    712
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    A noter que pour les exemples servant à calculer des valeurs (et pas des types) à la compilation, une syntaxe bien plus simple a finalement été mise en œuvre en C++11. Recherche constexpr pour en savoir plus.
    Ah oui, effectivement. C'est nettement mieux.

Discussions similaires

  1. LES TECHNIQUES DES SGBDR / MySQL rapide ???
    Par SQLpro dans le forum Langage SQL
    Réponses: 1
    Dernier message: 12/09/2003, 11h16
  2. [Compilateurs] Sites techniques
    Par Traroth dans le forum Langages de programmation
    Réponses: 4
    Dernier message: 26/03/2003, 09h11
  3. [Technique] Conflits entre plusieurs requêtes
    Par Neowile dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 24/03/2003, 09h37
  4. [Technique] Intérêt des index
    Par ddams dans le forum Décisions SGBD
    Réponses: 10
    Dernier message: 04/11/2002, 15h11
  5. [Technique] Index, comment font les moteurs de recherche ?
    Par bat dans le forum Décisions SGBD
    Réponses: 4
    Dernier message: 25/10/2002, 15h41

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