Schablone metaprogramming

Schablone metaprogramming ist eine metaprogramming Technik, in der Schablonen durch einen Bearbeiter verwendet werden, um vorläufigen Quellcode zu erzeugen, der durch den Bearbeiter mit dem Rest des Quellcodes verschmolzen und dann kompiliert wird. Die Produktion dieser Schablonen schließt Übersetzungszeit-Konstanten, Datenstrukturen ein, und vollendet Funktionen. Vom Gebrauch von Schablonen kann als Übersetzungszeit-Ausführung gedacht werden. Die Technik wird durch mehrere Sprachen, das am besten bekannte Wesen C ++, sondern auch Locke, D, und XL verwendet.

Schablone metaprogramming wurde gewissermaßen zufällig entdeckt: Sieh.

Eine andere Sprachunterstützung ähnliche wenn nicht stärkere Übersetzungszeit-Möglichkeiten (wie Lispeln-Makros), aber sind diejenigen außerhalb des Spielraums dieses Artikels.

Bestandteile der Schablone metaprogramming

Der Gebrauch von Schablonen als eine metaprogramming Technik verlangt zwei verschiedene Operationen: Eine Schablone muss definiert werden, und eine definierte Schablone muss realisiert werden. Die Schablone-Definition beschreibt die allgemeine Form des erzeugten Quellcodes, und der instantiation veranlasst einen spezifischen Satz des Quellcodes, von der allgemeinen Form in der Schablone erzeugt zu werden.

Schablone metaprogramming ist allgemein Turing-abgeschlossen, bedeutend, dass jede Berechnung expressible durch ein Computerprogramm, in einer Form, durch eine Schablone metaprogram geschätzt werden kann.

Schablonen sind von Makros verschieden. Ein Makro, das auch eine Übersetzungszeit-Spracheigenschaft ist, erzeugt Code Reihenverwenden-Textmanipulation und Ersatz. Makrosysteme haben häufig geistige Übersetzungszeit-Prozess-Fluss-Anlagen beschränkt und haben gewöhnlich an Bewusstsein der Semantik Mangel, und Typ-System ihrer dazugehörigen Sprache (sollte eine Ausnahme mit den Makros des Lispelns gemacht werden, die im Lispeln selbst geschrieben werden und Manipulation und Ersatz des Lispeln-Codes vertreten als Datenstrukturen im Vergleich mit dem Text einschließen).

Schablone metaprograms hat keine veränderlichen Variablen - d. h. keine Variable kann Wert ändern, sobald es deshalb initialisiert worden ist, kann Schablone metaprogramming als eine Form der funktionellen Programmierung gesehen werden. Tatsächlich führen viele Schablone-Durchführungen nur Fluss-Kontrolle durch recursion, wie gesehen, im Beispiel unten durch.

Das Verwenden der Schablone metaprogramming

Obwohl die Syntax der Schablone metaprogramming gewöhnlich von der Programmiersprache sehr verschieden ist, mit der es verwendet wird, hat es praktischen Nutzen. Einige allgemeine Gründe, Schablonen zu verwenden, sollen allgemeine Programmierung durchführen (das Vermeiden von Abteilungen des Codes, die abgesehen von einigen geringen Schwankungen ähnlich sind), oder automatische Übersetzungszeit-Optimierung wie das Tun von etwas einmal während der Übersetzung, aber nicht jedes Mal durchzuführen wenn das Programm - zum Beispiel geführt wird, indem es den Bearbeiter gehabt wird, entrollen Schleifen, um Sprünge und Schleife-Verminderung der Zählung zu beseitigen, wann auch immer das Programm durchgeführt wird.

Übersetzungszeit-Klassengeneration

Was genau "Programmierung während der Übersetzung" bedeutet, kann mit einem Beispiel einer Factorial-Funktion illustriert werden, die in der Nichtschablone C ++ mit recursion wie folgt geschrieben werden kann:

constexpr nicht unterzeichnete interne Nummer factorial (nicht unterzeichnete interne Nummer n) {\

kehren Sie (n == 0) zurück? 1: n * factorial (n-1);

}\interne

Const-Nummer x = factorial (4);//== (4 * 3 * 2 * 1 * 1) == 24

interne

Const-Nummer y = factorial (0);//== 0! == 1

</Quelle>

Der Code wird oben in der Durchlaufzeit durchführen, um den factorial Wert der Literale 4 und 0 zu bestimmen.

Durch das Verwenden der Schablone metaprogramming und Schablone-Spezialisierung, um die endende Bedingung für den recursion zur Verfügung zu stellen, kann der im Programm verwendete factorials, das Ignorieren jedes nicht verwendeten factorial, während der Übersetzung durch diesen Code berechnet werden:

Schablone

struct Factorial {\

enum {schätzen = N * Factorial

};Schablone

struct Factorial

enum {schätzen = 1};

};

//Factorial

//Factorialinterne

Const-Nummer x = Factorial

interne

Const-Nummer y = Factorial

</Quelle>

Der Code berechnet oben den factorial Wert der Literale 4 und 0 während der Übersetzung und verwendet das Ergebnis, als ob sie vorberechnete Konstanten waren.

Um im Stande zu sein, Schablonen auf diese Weise zu verwenden, muss der Bearbeiter den Wert seiner Rahmen während der Übersetzung wissen, der die natürliche Vorbedingung das hat

Übersetzungszeit-Codeoptimierung

Das factorial Beispiel ist oben ein Beispiel der Übersetzungszeit-Codeoptimierung, in der alle durch das Programm verwendeten factorials vorkompiliert und als numerische Konstanten an der Kompilation eingespritzt werden, sowohl Durchlaufzeit oben als auch Speicherfußabdruck sparend. Es, ist jedoch, eine relativ geringe Optimierung.

Da ein anderer, bedeutender, Beispiel des Übersetzungszeit-Entrollens der Schleife, Schablone metaprogramming verwendet werden kann, um Vektor-Klassen der Länge-n zu schaffen (wo n während der Übersetzung bekannt ist). Der Vorteil über einen traditionelleren Vektoren der Länge-n ist, dass die Schleifen entrollt werden können, auf sehr optimierten Code hinauslaufend. Als ein Beispiel, denken Sie den Hinzufügungsmaschinenbediener. Eine Vektor-Hinzufügung der Länge-n könnte als geschrieben werden

Schablone

Vektor

{\

für (interne Nummer i = 0; ich

Wenn der Bearbeiter die Funktionsschablone realisiert, die oben definiert ist, kann der folgende Code erzeugt werden:

Schablone Vektor{\

Wert [0] + = rhs.value [0];

Wert [1] + = rhs.value [1];

geben Sie *this zurück;

}\</Quelle>

Der optimizer des Bearbeiters sollte im Stande sein, die Schleife zu entrollen, weil der Schablone-Parameter eine Konstante während der Übersetzung ist.

Nehmen Sie jedoch Verwarnung, weil das Code bloat verursachen kann, weil getrennter entrollter Code für jeden 'N' erzeugt wird (Vektor-Größe), realisieren Sie damit.

Statischer polymorphism

Polymorphism ist eine allgemeine Standardprogrammiermöglichkeit, wo abgeleitete Gegenstände als Beispiele ihres Grundgegenstands verwendet werden können, aber wo die Methoden der abgeleiteten Gegenstände, als in diesem Code angerufen werden

Klassenbasis

{\

Publikum:

virtuelle leere Methode {std:: cout

löschen Sie pBase;

kehren Sie 0 zurück;}\</Quelle>

wo alle Beschwörungen von Methoden diejenigen der am meisten abgeleiteten Klasse sein werden. Dieses dynamisch polymorphe Verhalten wird (normalerweise) durch die Entwicklung von virtuellen Nachschlagetabellen für Klassen mit virtuellen Methoden, Tische erhalten, die in der Durchlaufzeit überquert werden, um die Methode zu identifizieren, angerufen zu werden. So hat Durchlaufzeit polymorphism notwendigerweise Ausführung oben zur Folge (obwohl auf modernen Architekturen die Gemeinkosten unwesentlich sind).

Jedoch in vielen Fällen ist das polymorphe erforderliche Verhalten invariant und kann während der Übersetzung bestimmt werden. Dann kann Curiously Recurring Template Pattern (CRTP) verwendet werden, um statischen polymorphism zu erreichen, der eine Imitation von polymorphism im Programmcode ist, aber der während der Übersetzung aufgelöst wird und so den virtuellen Tisch während Laufzeit lookups beseitigt. Zum Beispiel:

Schablone

struct stützen

{\

leere Schnittstelle

{\

//...

static_cast

//...

}\

};

struct hat abgestammt: Basis

{\

leere Durchführung ;

};</Quelle>

Hier wird die Grundklassenschablone die Tatsache ausnutzen, dass Mitglied-Funktionskörper nicht realisiert werden, bis ihre Behauptungen, und wird sie Mitglieder der abgeleiteten Klasse innerhalb seiner eigenen Mitglied-Funktionen über den Gebrauch von a so an der Kompilation verwenden, die eine Gegenstand-Zusammensetzung mit polymorphen Eigenschaften erzeugt. Als ein Beispiel des wirklichen Gebrauchs wird der CRTP in der Zunahme iterator Bibliothek http://www.boost.org/libs/iterator/doc/iterator_facade.html. verwendet

Ein anderer ähnlicher Gebrauch ist der "Trick von Barton-Nackman", manchmal gekennzeichnet als "eingeschränkte Schablone-Vergrößerung", wohin allgemeine Funktionalität in eine Grundklasse gelegt werden kann, die nicht als ein Vertrag, aber als ein notwendiger Bestandteil verwendet wird, um conformant Verhalten geltend zu machen, während man Codeüberfülle minimiert.

Vorteile und Nachteile der Schablone metaprogramming

  • Übersetzungszeit gegen den Ausführungszeit-Umtausch: Wenn sehr viel Schablone metaprogramming verwendet wird, kann Kompilation langsam werden; Abschnitt 14.7.1 [temp.inst] des aktuellen Standards definiert die Verhältnisse, unter denen Schablonen implizit realisiert werden. Als mit den meisten Aspekten von C ++ zahlen Sie nur dafür, was Sie verwenden: Das Definieren einer Schablone deutet nicht an, dass es realisiert wird, und das Realisieren einer Klassenschablone seine Mitglied-Definitionen nicht veranlasst, realisiert zu werden. Abhängig vom Stil des Gebrauches können Schablonen entweder schneller oder langsamer kompilieren als handgerollter Code.
  • Allgemeine Programmierung: Schablone metaprogramming erlaubt dem Programmierer, sich auf Architektur und Delegierten auf dem Bearbeiter die Generation jeder durch den Kundencode erforderlichen Durchführung zu konzentrieren. So kann Schablone metaprogramming aufrichtig allgemeinen Code vollbringen, Codeminimierung und bessere Haltbarkeit erleichternd.
  • Lesbarkeit: In Bezug auf C ++ sind die Syntax und Idiome der Schablone metaprogramming im Vergleich zu herkömmlichem C ++ Programmierung esoterisch, und Schablone metaprograms kann sehr schwierig sein zu verstehen. Metaprograms kann so schwierig sein, durch Programmierer aufrechtzuerhalten, die in der Schablone metaprogramming unerfahren sind (obwohl das mit der Durchführung der Sprache der Schablone metaprogramming Syntax ändern kann). Andererseits kann Schablone metaprogramming häufig verwendet werden, um Programme viel kürzer und einfacher, und so lesbarer zu machen.

Siehe auch

  • Metaprogramming
  • Vorverarbeiter
  • Parametrischer polymorphism
  • Variadic Schablonen
  • Übersetzungszeit-Funktionsausführung
  • Ulrich W. Eisenecker: Generative Programmierung: Methoden, Werkzeuge, und Anwendungen, Addison-Wesley, internationale Standardbuchnummer 0-201-30977-7
  • Andrei Alexandrescu: Moderner C ++ Design: Allgemeine Programmier- und Designmuster Angewandt, Addison-Wesley, internationale Standardbuchnummer 3-8266-1347-3
  • David Abrahams, Aleksey Gurtovoy: C ++ Schablone Metaprogramming: Konzepte, Werkzeuge und Techniken von der Zunahme und Darüber hinaus, Addison-Wesley, internationale Standardbuchnummer 0-321-22725-5
  • David Vandervoorde, Nicolai M. Josuttis: C ++ Schablonen: Der Ganze Führer, Addison-Wesley, die internationale Standardbuchnummer 0-201-73484-2
  • Manuel Clavel: Nachdenken im Neuschreiben der Logik: Metalogical Fundamente und Metaprogramming Anwendungen, internationale Standardbuchnummer 1-57586-238-7

Außenverbindungen


Source is a modification of the Wikipedia article Template metaprogramming, licensed under CC-BY-SA. Full list of contributors here.
Das Gegenstand-Schneiden / F-Null (Videospiel)
Impressum & Datenschutz