C++-Metaprogrammierung
C++-Metaprogrammierung ist eine Technik der Metaprogrammierung in C++. Also eien Technik um Programmcode von Programmcode generieren zu lassen. Dabei kommen besonders Templates zum Einsatz, daher spricht man auch von Templatemetaprogrammierung. Es gibt aber auch Metaprogrammierung über C-Makros.
Funktionsweise
Dei der Templatemetaprogrammierung macht man sich zu nutze, dass Templates während des Compilierprozesses ausgewertet werden. So kann man mit Hilfe von Templatespezialisierung Code schreiben, der zur Compilezeit ausgewertet wird und erst den eigentlichen Code generiert. Dies verlängert zwar die Dauer des compilierens, verkürzt aber die Laufzeit.
Die Templatemetaprogrammierung ist ein sehr mächtiges Feature und wurde für C++ relativ gut studiert und erforscht. So gibt es zum Beispiel eine Implementierung eines Lisp-Derivats [1] oder ein Parserframework [2] direkt in C++-Templates. Andrei Alexandrescu gilt als einer der Vordenker dieser Technik, die er besonders mit seinem Buch Modern C++ Design und die in dem Buch entwickelte Loki-Bibliothek bekannt machte.
Besonders die Boost-Bibliothek enthält viel Code für die Templatemetaprogrammierung.
Beispiel
Potenzberechnung in Templates.
#include <iostream>
template<long B,unsigned long E>
struct pow_helper {
static const double value;
};
template<long B,unsigned long E>
const double pow_helper<B,E>::value=B*pow_helper<B,E-1>::value;
template<long B>
struct pow_helper<B,0> {
static const double value;
};
template<long B>
const double pow_helper<B,0>::value=1;
template<long B,long E>
struct power {
static const double value;
};
template<long B,long E>
const double power<B,E>::value= E<0 ? 1.0/pow_helper<B,E<0 ? -E : E>::value :
pow_helper<B,E<0 ? -E : E>::value;
int main() {
std::cout << power<10,-3>::value << std::endl;
}
Der Code funktioniert so, dass das power-Template aufgerufen wird. Dies wertet nun aus, ob der Exponent negativ ist und rechnet in dem Fall . Zum Berechnen der eigentlichen Potenz wird die Struktur pow_helper benutzt. Diese ruft rekursiv sich selbst auf, wobei der Exponent immer um 1 reduziert wird. pow_helper besitzt eine Spezialisierung für den Fall, dass der Exponent 0 ist und liefert in dem Fall 1.
Also lässt sich der Code als
P(B,E) := B * P(B,E-1)
P(B,0) := 1
etwas leserlicher beschreiben.
Siehe
Weblinks
- Loki-Lib
- Boost::MPL
- Andrei Alexandrescus Homepage
- C++.de FAQ
- Objektorientierte Programmierung für Dummies - Bonuskapitel Template-Metaprogrammierung
Bücher
- Andrei Alexandrescu: Modernes C++ Design - Generische Programmierung und Entwurfsmuster angewendet, mitp, ISBN 3-8266-1347-3, das Standardwerk zur C++-Metaprogrammierung
- David Vandervoorde, Nicolai M. Josuttis: C++ Templates: The Complete Guide, Addison-Wesley Professional, ISBN 0-2017-3484-2