2008-10-26 6 views
13

Diese Frage existiert, weil es historische Bedeutung hat, aber es ist nicht gut betrachtet, themenbezogene Frage für diese Seite, so bitte nicht als Beweismittel verwenden, die Sie hier ähnliche Fragen stellen können.Was sind die coolsten Beispiele für Metaprogrammierung, die Sie in C++ gesehen haben?

Weitere Informationen: https://stackoverflow.com/faq


Was sind die coolsten Beispiele für metaprogramming, die Sie in C++ gesehen haben?
Was sind einige praktische Anwendungen von Metaprogrammierung, die Sie in C++ gesehen haben?

+0

Ich denke Boost Metaparse ist eine wirklich erstaunliche Sache https://github.com/boostorg/metaparse https://github.com/sabel83/metaparse_tutorial –

Antwort

23

Persönlich denke ich Boost.Spirit ist ein ziemlich erstaunliches Beispiel für Meta-Programmierung. Es ist ein vollständiger Parser-Generator, mit dem Sie Grammatiken mit C++ - Syntax ausdrücken können.

+1

+1: Geist ist ziemlich krank. Vielleicht möchten Sie auf eine neuere Version von Spirit verlinken? Diese Version scheint ein wenig alt zu sein. – n1ckp

+0

@ n1ck: danke, ich habe den Link aktualisiert – Ferruccio

7

Coolste Metaprogrammierung Beispiel: Tricking der Compiler in eine Liste von Primzahlen zu berechnen. Nicht sehr praktisch, aber beeindruckend.

Eine praktische Verwendung sind Kompilierungszeit-assert-Anweisungen, d. H., Die einen Kompilierungsfehler verursachen, wenn eine boolesche Bedingung nicht gilt.

+0

+1 für statische Behauptung –

2

luabind ist ein ziemlich cooles praktisches Beispiel, eine ganz nette Bindung dsl für die Bindung von C++ Klassen LUA

19

Die praktischste Verwendung von Meta-Programmierung wird einen Laufzeitfehler in einen Kompilierung Fehler drehen.

Beispiel: Rufen wir die Schnittstelle IFoo. Eines meiner Programme befasste sich mit einem COM-Objekt, das mehrere Pfade zu IFoo hatte (sehr komplizierte Vererbungshierarchie). Leider erkannte die zugrundeliegende COM-Objekt-Implementierung nicht, dass sie mehrere Pfade zu IFoo hatte. Sie nahmen an, dass es immer der Linkste war. So in ihrem Code, war das folgende Muster sehr häufig

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

Die zweite IFoo obwohl die resultierenden „p“ verursachte Zeiger vollständig ungültig sein (Mehrfachvererbung ist gefährlich).

Die langfristige Lösung bestand darin, dass der Besitzer des COM-Objekts dieses Problem beheben konnte. Kurzfristig musste ich jedoch sicherstellen, dass ich immer den richtigen IFoo zurückgab. Ich konnte garantieren, dass ich den passenden IFoo hatte, indem ich eine QI verwendete und implizierte Umwandlungen zu IFoo vermied. Also habe ich eine neue CComPtr <> Implementierung erstellt und der gleichen Methode die folgende Überschreibung hinzugefügt.

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

Dies zeigte schnell jeden einzelnen Ort, den ich implizit auf IFoo gegossen.

+1

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

+2

Ist das Metaprogrammieren? Sieht wie eine einfache Spezialisierung aus. – fizzer

+1

In vielerlei Hinsicht ist Metaprogrammierung Spezialisierung. Dies ist ein ziemlich einfaches Beispiel für Meta-Programmierung (aber sehr effektiv). Ich denke, es ist einer der praktischeren Aspekte der Meta-Programmierung, die dich davor bewahrt, dich selbst zu verletzen. – JaredPar

12

Blitz++ macht einige beeindruckende Dinge mit Vorlagen (zum Beispiel kann eine einzelne lesbare Codezeile in eine Reihe von Schleifen über ein multidimensionales Array umgewandelt werden, automatisch optimiert für die beste Traversierungsreihenfolge).

+0

Wow. Ich weiß, dass es ein bisschen spät ist, aber wenn du die Chance hast, auf die fragliche Zeile hinzuweisen, wäre das großartig. – Praxeolitic

+0

Link scheint geändert zu werden – TankorSmash

4

Ich würde Boost.Lambda, Boost.Function und Boost.Bind und die Art und Weise sagen, dass sie alle nahtlos zusammenarbeiten. Sie bieten eine wirklich glatte Oberfläche und machen funktionale Programmierung so einfach wie möglich in einer Sprache, die nicht wirklich dafür gebaut wurde.

+0

Diese sind alle jetzt in C++ 11 nativ. – TankorSmash

0

Ich habe vor nicht allzu langer Zeit eine Frage gestellt: C++ Runtime Knowledge of Classes und die Antwort, die ich von einem StackOverflow-Benutzer "Denice" erhielt, war eine URL zu einer Website Meatspace: C++ runtime class registration.

Ich denke, das ist eine wirklich coole Möglichkeit, Vorlagen zu verwenden und Objekte zu instantiieren, die alle von einer Basisklasse abgeleitet sind, so dass wenn ich 10 C++ Dateien habe, sie alle AUTO_REGISTER_BASE() ganz unten hinzufügen können Wenn alles fertig und verknüpft ist, werden nur die Klassen/Dateien registriert, die es erstellt haben, so dass Sie zur Laufzeit zwischen den verschiedenen verfügbaren Klassen wechseln können, und diejenigen, die nicht verfügbar sind, sind nicht registriert und können daher nicht zufällig sein namens.

Es gibt viele verschiedene OS-abhängige Möglichkeiten, um Ereignisbenachrichtigungen zu machen (select(), kqueue(),/dev/epoll, Solaris hat seine eigene Sache, poll()), und ich brauchte einen Weg, um alle Klassendateien existieren in dem Verzeichnis, aber abhängig davon, auf welchem ​​OS das Makefile ausgeführt wurde, würde es nur bestimmte kompilieren. Ich brauchte eine Möglichkeit, um zu wissen, welche zur Zeit verfügbar waren, und einen Weg für den Programmierer zu haben, die Bibliothek zu benutzen, um ihre Präferenz zu wählen, wenn es aber nicht möglich war, diejenige zu verwenden, die für die Plattform am logischsten war Gewichte zugewiesen haben).

Der Code oben half mir, dieses Ziel zu erreichen, mit einigen heftigen Modifikationen, aber es half mir dennoch!

12

nicht von der praktischen Anwendung (außer vielleicht für Compiler-Tests), aber metatrace ist ein Whitted-Style (dh rekursive und deterministischem) Raytracer, der Bilder wie diese zum Zeitpunkt der Kompilierung erzeugt:

metatrace example

Einige komplexere Teile of the code können in fixp.hh gesehen werden, die eine Implementierung von Festkomma sqrt hat unter Verwendung der Heron Methode oder die sphere.hh ray/Kugel-Schnittpunktberechnung zeigt.

Verwandte Themen