2008-10-26 7 views
13

Cette question existe parce qu'il a une signification historique, mais ce n'est pas considéré comme un bon, sur le sujet question pour ce site, donc s'il vous plaît ne pas l'utiliser comme preuve que vous pouvez poser semblables questions.Quels sont les exemples les plus cool de métaprogrammation que vous avez vu en C++?

Plus d'infos: https://stackoverflow.com/faq


Quels sont les exemples les plus cool de métaprogrammation que vous avez vu en C++?
Quelles sont les utilisations pratiques de la métaprogrammation que vous avez vues en C++?

+0

Je pense Boost Metaparse est une chose vraiment incroyable https://github.com/boostorg/metaparse https://github.com/sabel83/metaparse_tutorial –

Répondre

23

Personnellement, je pense que Boost.Spirit est un exemple assez étonnant de méta-programmation. C'est un générateur d'analyseur complet qui vous permet d'exprimer des grammaires en utilisant la syntaxe C++.

+1

+1: l'esprit est assez malade. Vous voudrez peut-être créer un lien vers une version plus récente de spirit? Cette version semble un peu vieille. – n1ckp

+0

@ n1ck: merci, j'ai mis à jour le lien – Ferruccio

7

Exemple de métaprogrammation le plus cool: tromper le compilateur dans le calcul d'une liste de nombres premiers. Pas très pratique, mais impressionnant.

Une utilisation pratique est des instructions assert de compilation, c'est-à-dire provoquant une erreur de compilation si une condition booléenne ne tient pas.

+0

+1 pour l'affirmation statique –

2

luabind est un exemple pratique assez cool, un bon dsl liaison agréable pour la liaison des classes C++ Lua

19

L'utilisation la plus pratique de la programmation méta tourne une erreur d'exécution dans une erreur de compilation.

Exemple: Appelons l'interface IFoo. Un de mes programmes traitait un objet COM qui avait plusieurs chemins vers IFoo (hiérarchie d'héritage très compliquée). Malheureusement, l'implémentation de l'objet COM sous-jacent ne s'est pas rendu compte qu'ils avaient plusieurs chemins vers IFoo. Ils ont supposé que c'était toujours le plus à gauche. Donc, à l'intérieur de leur code, le modèle suivant était très commun

void SomeMethod(IFoo* pFoo) { 
     CFooImpl *p = (CFooImpl)pFoo; 
    } 

La deuxième IFoo si causé le résultat pointeur « p » pour être complètement invalide (héritage multiple est dangereux).

La solution à long terme consistait à demander au propriétaire de l'objet COM de résoudre ce problème. À court terme, je devais m'assurer que je retournais toujours le bon IFoo. Je pourrais garantir que j'ai eu l'IFoo approprié en utilisant un QI et en évitant tout moulage implicite à IFoo. J'ai donc créé une nouvelle implémentation de CComPtr <> et ajouté le remplacement suivant à la méthode equal.

template <typename T> 
CComPtr<T>& operator=(const T* pT) { 
// CComPTr Assign logic 
} 
template <> 
CComPtr<IFoo> operator=<IFoo>(const IFoo* pT) { 
    COMPILE_ERROR(); 
} 

Cela a rapidement révélé chaque endroit implicitement casté à IFoo.

+1

QI = QueryInterface http://msdn.microsoft.com/en-us/library/ms682521(VS.85).aspx – JaredPar

+2

Est-ce une métaprogrammation? On dirait une simple spécialisation. – fizzer

+1

À bien des égards, la métaprogrammation est une spécialisation. C'est un exemple assez simple de méta programmation (mais très efficace). Je pense que cela représente l'un des aspects les plus pratiques de la programmation méta, vous empêchant de vous faire du mal. – JaredPar

12

Blitz++ fait des choses impressionnantes avec des modèles (par exemple, une seule ligne de code lisible peut être transformée en un ensemble de boucles sur un tableau multidimensionnel, automatiquement optimisé pour le meilleur ordre de traversée).

+0

Wow. Je me rends compte que c'est un peu tard, mais si vous avez une chance de souligner la ligne en question ce serait génial. – Praxeolitic

+0

Le lien semble être modifié – TankorSmash

4

Je devrais dire Boost.Lambda, Boost.Function, et Boost.Bind et la façon dont ils fonctionnent tous ensemble de façon transparente. Ils fournissent une interface vraiment lisse et rendent la programmation fonctionnelle aussi facile que possible dans un langage qui n'était pas vraiment construit pour cela.

+0

Ils sont tous natifs dans C++ 11 maintenant. – TankorSmash

0

Je pose une question de ne pas il y a longtemps: C++ Runtime Knowledge of Classes et la réponse que je suis revenu d'un utilisateur StackOverflow « Denice » est une URL vers un site Web Meatspace: C++ runtime class registration.

Je pense que c'est une manière vraiment cool d'utiliser des templates et d'instancier des objets qui sont tous dérivés d'une classe de base, donc quand j'ai 10 fichiers C++, ils peuvent tout simplement ajouter AUTO_REGISTER_BASE() en bas, et Lorsque tout est terminé et lié, seules les classes/fichiers qui l'ont créé seront enregistrés. Ainsi, à l'exécution, vous pouvez basculer entre les différentes classes disponibles et celles qui ne sont pas disponibles ne sont pas enregistrées et ne peuvent donc pas être accidentellement appelé.

Il existe de nombreuses façons de faire des notifications d'événements dépendantes du système d'exploitation (select(), kqueue(),/dev/epoll, Solaris a sa propre chose, poll()), et j'avais besoin de tous les Les fichiers de classe existent dans le répertoire, mais en fonction du système d'exploitation sur lequel le Makefile a été exécuté, il n'en compile que certains. J'avais besoin d'un moyen de savoir au moment de l'exécution lesquels étaient disponibles, et d'avoir un moyen pour le programmeur d'utiliser la bibliothèque pour sélectionner sa préférence, mais s'il était indisponible pour utiliser celui qui avait le sens le plus logique pour la plate-forme avoir des poids qui leur sont assignés).

Le code ci-dessus m'a aidé à atteindre cet objectif, avec quelques modifications lourdes, mais cela m'a quand même aidé!

12

Pas d'utilisation pratique (sauf peut-être pour le test du compilateur), mais metatrace est un Whitted-style (c.-à-récursive et déterministe) ray tracer qui génère des images comme celles au moment de la compilation:

metatrace example

Certaines parties plus complexes of the code peut être vu dans fixp.hh, qui a une mise en œuvre de sqrt à virgule fixe en utilisant la méthode Heron, ou sphere.hh qui montre le calcul, d'intersection de la sphère ray /.

Questions connexes