Template Metaprogrammierung



  • Da hast du Recht Nexus, auf solche Fragen habe ich mich innerlich auch schon vorbereitet. Allerdings habe ich maximal 20 Minuten Zeit und meine Zuhörerschaft besteht zu 100% aus Java Programmierern, weil dies nunmal die erste Sprache an dieser Hochschule ist. (Wie ich dann zu so einem Thema gekommen bin, lasse ich mal außen vor)

    Ich muss also erstmal grob bzw. ausreichend erklären, was Templates überhaupt sind, wie sie funktionieren ect. Darauf aufbauend kann ich dann erst mit meinem eigentlichen Thema anfangen. Erklären was möglich ist, ein paar Beispiele zeigen und erläutern, um letztendlich zu den Vor und Nachteilen der Metaprogrammierung zu kommen und diese wieder zu erklären.

    Bei Static Assertions und Policy Based Design schau ich mal, wie das benötigte Wissen dafür aussieht. Auch wenn ich selbst diese beiden Formulierungen noch nicht häufig gehört habe, habe ich eine Vorstellung, was sich dahinter verbergen könnte (Bei Policy Based Design tippe ich spontan auf sowas wie den Allocator-Parameter bei den STL-Containern, richtig?). Jedenfalls werde ich mir dazu noch die eine oder andere Sache durchlesen.

    Edit:
    Ok, die beiden Themen kann ich wohl noch als konkrete Nutzung mit einbringen, vielen Dank 🙂

    Edit2:
    Danke drakon, wird gemacht 😃



  • -Shelling- schrieb:

    Was ich noch suche ist ein etwas komplexeres Beispiel.

    Du könntest z.B. ein Metaprogramm machen, das die Goldbachsche Vermutung für eine gegebene Zahl nachprüft. Oder du implementierst die Cantorsche Bijektion \begin{math}\mathbb{N}\rightarrow{\mathbb{N}}\times{\mathbb{N}}\end{math} . Oder du variierst die Goldbach-Vermutung und läßt den Compiler nachrechnen, ob eine Zahl auch Differenz zweier Primzahlen ist. (Wie die zugehörige Vermutung heißt, weiß ich leider nicht; ich habe die Idee aus "Gödel Escher Bach".) Oder du läßt den Compiler die Goldbach-Vermutung widerlegen.

    Wenn ich mich nicht täusche, erfordern die letzten beiden Beispiele mehr oder weniger die Turing-Vollständigkeit der "Sprache" TMP.



  • was zwar rekursion ist, aber eig ganz sinnvoll wie ich finde, wäre wenn man das potenzieren in templates verpackt, aber nicht nur so simpel wie auf wikipedia, sondern auch für wurzeln und negative exponenten

    wobei mir fällt da grad ein, template parameter können nur ganzahlen sein oder?!?
    dann wäre das nämlich schon wieder nutzlos...



  • Ganzzahlige Potenzen kommen in der Praxis schon noch vor. 🙂



  • audacia schrieb:

    Wenn ich mich nicht täusche, erfordern die letzten beiden Beispiele mehr oder weniger die Turing-Vollständigkeit der "Sprache" TMP.

    Die Turing-Vollständigkeit von C++-Templates ist theoretisch gegeben. Was nicht gegeben ist, ist die genügende Unterstützung des Compilers. Beispielsweise steigen die meisten Compiler schon bei einer relativ geringen Rekursionstiefe (17 ist vom Standard empfohlen) von templates aus und schmeißen hin: http://www.netvor.sk/~umage/docs/C++ Templates are Turing Complete.pdf

    Auf dem 2009er Foren-Treffen hatten wir "Joseph's Problem" zu lösen. Beim Versuch, das per TMP-Spielerei vom Compiler erledigen zu lassen hat der MSVC 2008 schon bei ziemlich kleinen Werten aufgegeben 😞


  • Mod

    Angeregt von einem anderen Thread in diesem Forum, kam mir die Idee, dass man elektrische Widerstandswerte aus Farbcodierungen berechnen könnte. Dann könnte man zur Compilezeit systematisch eine Liste aller möglichen Widerstände erstellen lassen. Fällt zwar auch ein bisschen unter "Wozu braucht man das?" ist aber immerhin eine spannendere Aufgabe als eine Fakultät zu berechnen und kann auch nicht zur Programmierzeit durch einen schnellen Griff zum Taschenrechner ersetzt werden.

    Weiterhin kommen hier im Forum regelmäßig dumme Fragen nach Hausaufgaben, die dann oft mit Templatemetaprogrammen beantwortet werden. Oder Geschwindigkeitsoptimierungsfragen, wo Compilezeitlösungen auch immer ganz vorne mit dabei sind. Beispiele:
    Optimiertes Zählen der Dezimalstellen einer Zahl. War jedoch letztendlich langsamer als die if-Kaskade.
    Frage-Antwort Spiel bei dem alle möglichen Pfade zur Compilezeit ausgewertet werden.



  • Die größten TMP-Helden sind sowieso die Macher von Boost. Meine Favoriten: boost.proto und das damit implementierte boost.spirit



  • -Shelling- schrieb:

    Da hast du Recht Nexus, auf solche Fragen habe ich mich innerlich auch schon vorbereitet. Allerdings habe ich maximal 20 Minuten Zeit und meine Zuhörerschaft besteht zu 100% aus Java Programmierern

    Umso mehr solltest du darauf achten, ihre Vorurteile nicht zu bestätigen! Sie müssen nach dem Vortrag enttäuscht darüber sein, dass Java sowas nicht bietet :p



  • Erstmal Entschuldigung für meine lange Abwesenheit
    Zweitens dann vielen vielen Dank für eure Anregungen und Ideen.

    Ich hab mir eure Ideen angeschaut und mich dazu entschlossen, auch etwas komplexere Sachen als Beispiele aufzunehmen. Den Rest werde ich wohl als weitere Wegweiser für die Zuhörer nutzen.

    Nexus schrieb:

    -Shelling- schrieb:

    Da hast du Recht Nexus, auf solche Fragen habe ich mich innerlich auch schon vorbereitet. Allerdings habe ich maximal 20 Minuten Zeit und meine Zuhörerschaft besteht zu 100% aus Java Programmierern

    Umso mehr solltest du darauf achten, ihre Vorurteile nicht zu bestätigen! Sie müssen nach dem Vortrag enttäuscht darüber sein, dass Java sowas nicht bietet :p

    Ich halte die C++ Flagge schon recht häufig hoch, du glaubst gar nicht, wie oft mich die Java Generics stören 😃



  • Boost.Spirit wollte ich auch gerade erwähnen.

    Aber auch andere Boost Libraries machen nicht halt vor TMP, allen voran natürlich die Boost.MPL 🙂
    Anwendungsbeispiele findet man z.B. in der Boost.Statechart oder auch in so "ordinären" Libraries/Klassen wie Boost.Variant (Stichwort Static Visitor).



  • drakon schrieb:

    Denkanstösse sind schwierig. Man muss einfach mal eine Idee haben was man so machen könnte (und das ist sehr vieles; siehe dazu mal "Modern C++ Design" von Andrej Alexandrescu).
    Man kann eigentlich noch recht viele Probleme (oder zumindest Teile davon) auf etwas mappen, dass zur Kompilierungszeit gemacht werden kann und dann kann man da üblicherweise auch etwas mit Metaprogrammierung erreichen.

    Mal eine kleine Idee, die mir während einer Zugfahrt gekommen ist:
    http://www.drakon.ch/index.php?id=&offset=2&mobile=0&show_entry=94

    musste da die römischen Zeichen und Regeln mit dem Telefon nachschlagen.. 😛

    Ist natürlich nur eine Spielerei, aber immerhin nicht das übliche Rekursive Gedöns und nicht so abgedreht wie Typlisten. 😉

    Der Trick ist doch das #define am Anfang. Zählen defines auch zu Metaprogrammierung?



  • hhhhmmmmm schrieb:

    Der Trick ist doch das #define am Anfang. Zählen defines auch zu Metaprogrammierung?

    Das #define erspart nur lästiges Tippen. Man könnte es genauso gut ausschreiben oder in eine Metafunktion packen. Die eigentliche Metaprogrammierung liegt ja woanders.
    Und prinzipiel: #define und Metaprogrammierung können sich mitunter ganz gut ergänzen.



  • ipsec schrieb:

    [...]Das #define erspart nur lästiges Tippen.[...]

    Nichts anderes tut TMP letzten Endes auch. Und ja, Defines zählen zur Metaprogrammierung.


  • Mod

    Tachyon schrieb:

    ipsec schrieb:

    [...]Das #define erspart nur lästiges Tippen.[...]

    Nichts anderes tut TMP letzten Endes auch.

    Nein. Das Templatemetaprogramm wird tatsächlich ausgeführt und etwas berechnet. Das kann man nicht durch Tipparbeit ersetzen, man braucht mindestens noch einen Taschenrechner und ein Gerät welches Entscheidungen treffen kann. Sprich: einen Computer.

    Und ja, Defines zählen zur Metaprogrammierung.

    Ja, ich würde sie trotzdem auch dazu zählen, weil sie in kleinem Umfang etwas erlauben, was der Metaprogrammierung sehr ähnlich ist (so lange man nicht hinter die Kulisse guckt).



  • SeppJ schrieb:

    Nein. Das Templatemetaprogramm wird tatsächlich ausgeführt und etwas berechnet.[...]

    Ein TMP erzeugt Programmcode aus Templatecode zur Compilezeit, welcher dann ausgeführt werden kann. Das tun Makros auch.



  • Anderswo schon mal verlinkt: http://vimeo.com/7211030 . Wenn ihr Macros aus Scheme oder Lisp sehen und verstehen wuerdet ... Naja, was soll's.


  • Mod

    Tachyon schrieb:

    SeppJ schrieb:

    Nein. Das Templatemetaprogramm wird tatsächlich ausgeführt und etwas berechnet.[...]

    Ein TMP erzeugt Programmcode aus Templatecode zur Compilezeit, welcher dann ausgeführt werden kann. Das tun Makros auch.

    Nein! Das ist ein ganz großer Unterschied zwischen einer simplen Textersetzung und einer Turing-vollständigen Programmiersprache.

    Erklär mir mal, wie du ein static assert durch mehr Tippen ausgleichen willst. Oder wie du das Berechnen von Zahlenfolgen zur Compilezeit durch Tippen ausgleichen willst (außer mit einem anderen Programm diese Zahlen zu Berechnen und dann abzutippen).



  • SeppJ schrieb:

    Tachyon schrieb:

    SeppJ schrieb:

    Nein. Das Templatemetaprogramm wird tatsächlich ausgeführt und etwas berechnet.[...]

    Ein TMP erzeugt Programmcode aus Templatecode zur Compilezeit, welcher dann ausgeführt werden kann. Das tun Makros auch.

    Nein! Das ist ein ganz großer Unterschied zwischen einer simplen Textersetzung und einer Turing-vollständigen Programmiersprache.

    Erklär mir mal, wie du ein static assert durch mehr Tippen ausgleichen willst. Oder wie du das Berechnen von Zahlenfolgen zur Compilezeit durch Tippen ausgleichen willst (außer mit einem anderen Programm diese Zahlen zu Berechnen und dann abzutippen).

    Den Static-Assert kann ich z.B. durch tippen bekommen, indem ich an jeder Stelle an der geprüft werden soll ein Array hinbastel, dass im Fehlerfall die Größe -1 bekommt.
    Berechnungen z.B. N! bekommt ich, indem ich den Code bis N von Hand eintippe. (N=5 -> 2 * 3 * 4 * 5 -> mehr Tipparbeit). Der TMP-Code für ! wird ja nicht zur Laufzeit ausgeführt, sondern es wird zur Compilezeit eine Konstante erzeugt.



  • Tachyon schrieb:

    SeppJ schrieb:

    Tachyon schrieb:

    SeppJ schrieb:

    Nein. Das Templatemetaprogramm wird tatsächlich ausgeführt und etwas berechnet.[...]

    Ein TMP erzeugt Programmcode aus Templatecode zur Compilezeit, welcher dann ausgeführt werden kann. Das tun Makros auch.

    Nein! Das ist ein ganz großer Unterschied zwischen einer simplen Textersetzung und einer Turing-vollständigen Programmiersprache.

    Erklär mir mal, wie du ein static assert durch mehr Tippen ausgleichen willst. Oder wie du das Berechnen von Zahlenfolgen zur Compilezeit durch Tippen ausgleichen willst (außer mit einem anderen Programm diese Zahlen zu Berechnen und dann abzutippen).

    Den Static-Assert kann ich z.B. durch tippen bekommen, indem ich an jeder Stelle an der geprüft werden soll ein Array hinbastel, dass im Fehlerfall die Größe -1 bekommt.
    Berechnungen z.B. N! bekommt ich, indem ich den Code bis N von Hand eintippe. (N=5 -> 2 * 3 * 4 * 5 -> mehr Tipparbeit). Der TMP-Code für ! wird ja nicht zur Laufzeit ausgeführt, sondern es wird zur Compilezeit eine Konstante erzeugt.

    Das war gar nicht die Frage. Da C++ auch ohne TMP Turing-vollständig ist, kannst du alle Berechnungen von TMP-Programmen natürlich auch ohne TMP berechnen.



  • Michael E. schrieb:

    Das war gar nicht die Frage. Da C++ auch ohne TMP Turing-vollständig ist, kannst du alle Berechnungen von TMP-Programmen natürlich auch ohne TMP berechnen.

    Aber die Antwort.
    Ein TMP tut nichts anderes, als aus einer Template-Parametrisierung zur Compilezeit! Code/Konstanten/Typen zu generieren. Anstatt ein Template zu nehmen, kann ich auch den Code für alle im Programm benutzen Template-Parameter (die ja zur Compilezeit bereits existieren müssen), von Hand eintippen.


Anmelden zum Antworten