Template Metaprogrammierung
-
Ah, herzlichen Dank, sowas hab ich gesucht. Scheint auch nicht zu komplex zu sein, abgesehen von der typedef Geschichte für Neulinge, aber das sollte auch schnell zu erklären sein.
Hast du was dagegen, wenn ich den Code so übernehme?
-
Beispiele wie die Fakultät oder römische Zahlen sind zwar nett, um das Prinzip aufzuzeigen, aber bei mitdenkenden Zuhörern kannst du dich auf die Frage "Wozu braucht man das?" gefasst machen, auf die es nicht wirklich eine sinnvolle Antwort gibt. Denn sowas braucht genau niemand in einem Real-Life-Programm. Bei Techniken, die ohnehin schon sehr komplex sind und dann noch mit konstruierten Anwendungsfällen erklärt werden, entsteht schnell der Eindruck, es handle sich um praxisferne Experimente.
Von daher würde ich mindestens noch etwas erwähnen, was man in seinen C++-Programmen auch einsetzen kann. Ein paar Beispiele von tatsächlichen Anwendungen der Template-Metaprogrammierung:
- Static Assertions
- Policy Based Design
- Traits
- Erkennen, in welche Typenkategorie ein Typ gehört (z.B. integral)
Vieles davon ist natürlich nicht ganz einfach, aber besonders bei den ersten beiden kann man auch als mittelmässiger C++-Programmierer nachvollziehen, wozu sowas gut sein kann.
-
-Shelling- schrieb:
Hast du was dagegen, wenn ich den Code so übernehme?
Ne, nimm ruhig.
Ehre mich einfach in deinem Vortrag.. :p
-
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

-
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=94musste 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.
-
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.
-
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).