{"id":8030,"date":"2025-11-29T09:10:33","date_gmt":"2025-11-29T08:10:33","guid":{"rendered":"https:\/\/web-dev-weissblau.de\/microconsult\/?p=8030"},"modified":"2026-02-11T05:58:04","modified_gmt":"2026-02-11T04:58:04","slug":"programming-at-compile-time","status":"publish","type":"post","link":"https:\/\/www.microconsult.de\/en\/programmierung-zur-compilezeit\/","title":{"rendered":"Compile-time programming"},"content":{"rendered":"<p>Autor: Rainer Grimm<\/p>\n<h3>Beitrag &#8211; Embedded Software Engineering Kongress 2015<\/h3>\n<p><strong>Was haben klassische Template-Metaprogrammierung, die Funktionen der Type-Traits-Bibliothek und konstante Ausdr\u00fccke gemein? Sie werden alle zur Compilezeit ausgef\u00fchrt. Damit vereinen sie h\u00f6here Performanz mit erweiterter Funktionalit\u00e4t. H\u00f6here Performanz, da Berechnungen zur Lauf- auf die Compilezeit verlegt werden. Erweiterte Funktionalit\u00e4t, da Programmierung zur Compilezeit den resultierenden C++-Sourcecode modifizieren kann. Doch wie funktioniert die ganze Magie?<\/strong><\/p>\n<h2>Template-Metaprogrammierung<\/h2>\n<p>1994 entdeckte Erwin Unruh Template Metaprogrammierung durch einen Zufall. Sein Programm berechnete die ersten 30 Primzahlen zur Compilezeit. Die Ausgabe der Primzahlen war Teil der Fehlermeldung:<\/p>\n<p class=\"quellcode\">01 | Type `enum{}&#8216; can&#8217;t be converted to txpe `D&lt;2&gt;&#8216; (&#8222;primes.cpp&#8220;,L2\/C25).<\/p>\n<p class=\"quellcode\">02 | Type `enum{}&#8216; can&#8217;t be converted to txpe `D&lt;3&gt;&#8216; (&#8222;primes.cpp&#8220;,L2\/C25).<\/p>\n<p class=\"quellcode\">03 | Type `enum{}&#8216; can&#8217;t be converted to txpe `D&lt;5&gt;&#8216; (&#8222;primes.cpp&#8220;,L2\/C25).<\/p>\n<p class=\"quellcode\">04 | Type `enum{}&#8216; can&#8217;t be converted to txpe `D&lt;7&gt;&#8216; (&#8222;primes.cpp&#8220;,L2\/C25).<\/p>\n<p class=\"quellcode\">05 | Type `enum{}&#8216; can&#8217;t be converted to txpe `D&lt;11&gt;&#8216; (&#8222;primes.cpp&#8220;,L2\/C25).<\/p>\n<p class=\"quellcode\">06 | Type `enum{}&#8216; can&#8217;t be converted to txpe `D&lt;13&gt;&#8216; (&#8222;primes.cpp&#8220;,L2\/C25).<\/p>\n<p class=\"quellcode\">07 | Type `enum{}&#8216; can&#8217;t be converted to txpe `D&lt;17&gt;&#8216; (&#8222;primes.cpp&#8220;,L2\/C25).<\/p>\n<p class=\"quellcode\">08 | Type `enum{}&#8216; can&#8217;t be converted to txpe `D&lt;19&gt;&#8216; (&#8222;primes.cpp&#8220;,L2\/C25).<\/p>\n<p class=\"quellcode\">09 | Type `enum{}&#8216; can&#8217;t be converted to txpe `D&lt;23&gt;&#8216; (&#8222;primes.cpp&#8220;,L2\/C25).<\/p>\n<p class=\"quellcode\">10 | Type `enum{}&#8216; can&#8217;t be converted to txpe `D&lt;29&gt;&#8216; (&#8222;primes.cpp&#8220;,L2\/C25).<\/p>\n<p>Wie funktioniert die ganze Magie? Der Compiler instanziiert die Templates und erzeugt den tempor\u00e4ren C++ Sourceode, der zusammen mit dem restlichen Sourcecode \u00fcbersetzt wird. Zur Laufzeit des Programmes steht damit nur der ausf\u00fchrbare Code zur Verf\u00fcgung.<\/p>\n<p>So f\u00fchrt der Aufruf der Fakult\u00e4t Funktion\u00a0<span class=\"quellcode\">Factorial&lt;5&gt;::value<\/span>\u00a0in dem kleinen Codebeispiel dazu, dass der Wert zur Compilezeit berechnet wird.<\/p>\n<p class=\"quellcode\">template &lt;int N&gt;<\/p>\n<p class=\"quellcode\">struct Factorial{<\/p>\n<p class=\"quellcode\">\u00a0\u00a0\u00a0 static int const value= N * Factorial&lt;N-1&gt;::value;<\/p>\n<p class=\"quellcode\">};<\/p>\n<p class=\"quellcode\">template &lt;&gt;<\/p>\n<p class=\"quellcode\">struct Factorial&lt;1&gt;{<\/p>\n<p class=\"quellcode\">\u00a0\u00a0\u00a0 static int const value = 1;<\/p>\n<p class=\"quellcode\">};<\/p>\n<p class=\"quellcode\">std::cout &lt;&lt; Factorial&lt;5&gt;::value &lt;&lt; std::endl;<\/p>\n<p class=\"quellcode\">std::cout &lt;&lt; 120 &lt;&lt; std::endl;<\/p>\n<div>\n<p>Sch\u00f6n zeigt die folgende Abbildung (siehe\u00a0<a title=\"Programmierung zur Compilezeit (PDF)\" href=\"https:\/\/www.microconsult.de\/wp-content\/uploads\/2025\/11\/fachinfo_ese_echt_programmierung_zur_compilzeit_grimm.pdf\" target=\"_blank\" rel=\"noopener\">PDF<\/a>), dass der Wert der Fakult\u00e4t von 5 bereits zur Laufzeit als Konstante vorliegt. Dabei instanziiert der Compiler den Ausdruck\u00a0<span class=\"quellcode\">Factorial&lt;5&gt;::value<\/span>. Um diesen Wert zu berechnen, ben\u00f6tigt er den Ausdruck\u00a0<span class=\"quellcode\">Factorial&lt;4&gt;::value<\/span>. Diese Rekursion endet dann, wenn der Wert\u00a0<span class=\"quellcode\">Factorial&lt;1&gt;::value<\/span>\u00a0ben\u00f6tigt wird, denn deren Wert ist 1.<\/p>\n<p>Funktionen wie die\u00a0<span class=\"quellcode\">Factorial\u00a0<\/span>Funktion, die zur Compilezeit ausgef\u00fchrt werden, werden Metafunktionen genannt. Sie besitzen ein paar interessante Eigenschaften. Neben Ganzzahlen k\u00f6nnen sie auch Typen und Klassen-Typen als Template-Parameter verwenden. Metafunktionen sind unter der Decke Klassen-Templates. Sie k\u00f6nnen ihre Daten nicht modifizieren, sondern erzeugen auf Bedarf neue Daten.<\/p>\n<p>Template-Metaprogrammierung, die auf Metafunktion basiert, die zur Compilezeit auf ihren Metadaten agieren, ist eine rein funktionale Subsprache in der imperativen Sprache C++. Diese funktionale Subsprache ist Turing-vollst\u00e4ndig [1], und entspricht in ihrer M\u00e4chtigkeit der der Programmiersprachen C++, C oder Java.<\/p>\n<p>Template Metaprogrammierung ist die Grundlage f\u00fcr viele Boost-Bibliotheken [2]. Das trifft auch auf die Type-Traits Bibliothek zu, die seit C++11 Teil des C++-Standards ist.<\/p>\n<h2>Die Type-Traits Bibliothek<\/h2>\n<p>Die Type-Traits Bibliothek erlaubt es, Typabfragen, -vergleiche und -transformationen zur Compilezeit auszuf\u00fchren. Sie ist eine Anwendung der Template-Metaprogrammierung und verfolgt for allem zwei Zwecke: Korrektheit und Optimierung:<\/p>\n<p><strong>Korrektheit<\/strong><\/p>\n<p>Die Type-Traits Bibliothek erlaubt es in Kombination mit dem\u00a0<span class=\"quellcode\">static_assert<\/span>\u00a0Ausdruck, verbindliche Bedingungen an den Sourcecode zu stellen, die zur Compilezeit angewendet werden.<\/p>\n<p>Der\u00a0<span class=\"quellcode\">qcd<\/span>-Algorithmus zur Berechnung des gr\u00f6\u00dften gemeinsamen Teilers zweier Ganzzahlen ist viel zu generisch. So l\u00e4sst er sich zwar mit Flie\u00dfkommazahlen, Strings und unterschiedlichen Datentypen wie\u00a0<span class=\"quellcode\">int (100)\u00a0<\/span>und\u00a0<span class=\"quellcode\">long int\u00a0<\/span>(10L) verwenden. Der Compiler quittiert dies aber mit einer sehr wortreichen Fehlermeldung.<\/p>\n<p class=\"quellcode\">#include &lt;iostream&gt;<\/p>\n<p class=\"quellcode\">#include &lt;type_traits&gt;<\/p>\n<p class=\"quellcode\">template&lt;typename T&gt;<\/p>\n<p class=\"quellcode\">T gcd(T a, T b){<\/p>\n<p class=\"quellcode\">\u00a0 if( b == 0 ) return a;<\/p>\n<p class=\"quellcode\">\u00a0 else return gcd(b, a % b);<\/p>\n<p class=\"quellcode\">}<\/p>\n<p class=\"quellcode\">int main(){<\/p>\n<p class=\"quellcode\">\u00a0 std::cout &lt;&lt; gcd(100,10) &lt;&lt; std::endl;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/\u00a0 10<\/p>\n<p class=\"quellcode\">\u00a0 std::cout &lt;&lt; gcd(100,33) &lt;&lt; std::endl;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/\u00a0 1<\/p>\n<p class=\"quellcode\">\u00a0 std::cout &lt;&lt; gcd(100,0) &lt;&lt; std::endl;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/\u00a0 100<\/p>\n<p class=\"quellcode\">\u00a0\u00a0std::cout &lt;&lt; gcd(3.5,4.0) &lt;&lt; std::endl;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ ERROR<\/p>\n<p class=\"quellcode\">\u00a0 std::cout &lt;&lt; gcd(&#8222;100&#8243;,&#8220;10&#8220;) &lt;&lt; std::endl;\u00a0\u00a0\u00a0 \/\/ ERROR<\/p>\n<p class=\"quellcode\">\u00a0 std::cout &lt;&lt; gcd(100,10L) &lt;&lt; std::endl;\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\/\/ ERROR<\/p>\n<p class=\"quellcode\">}<\/p>\n<\/div>\n<div><\/div>\n<div>Durch die Type-Traits Bibliothek lassen sich die Bedingungen an den Algorithmus explizit stellen. Und das alles ohne zus\u00e4tzliche Kosten f\u00fcr die Laufzeit des Programmes.<\/div>\n<div><\/div>\n<div>\n<p class=\"quellcode\">template&lt;typename T1, typename T2&gt;<\/p>\n<p class=\"quellcode\">typename\u00a0std::conditional&lt;(sizeof(T1)&lt;sizeof(T2)),T1,T2&gt;::type\u00a0gcd(T1 a, T2 b){<\/p>\n<p class=\"quellcode\">\u00a0 static_assert(std::is_integral&lt;T1&gt;::value, &#8222;T1 should be integral!&#8220;);<\/p>\n<p class=\"quellcode\">\u00a0 static_assert(std::is_integral&lt;T2&gt;::value, &#8222;T2 should be integral!&#8220;);<\/p>\n<p class=\"quellcode\">\u00a0 if( b == 0 )return a;<\/p>\n<p class=\"quellcode\">\u00a0 else return gcd(b, a % b);<\/p>\n<p class=\"quellcode\">}<\/p>\n<p>So pr\u00fcft der neue\u00a0<span class=\"quellcode\">qcd<\/span>-Algorithmus, ob die beiden Template-Argumente T1 und T2 Ganzzahlen sind:\u00a0<span class=\"quellcode\">std::is_integral&lt;T1&gt;::value.\u00a0<\/span>Als R\u00fcckgabetyp f\u00fcr den gr\u00f6\u00dften gemeinsamen Teiler gibt der\u00a0<span class=\"quellcode\">qcd<\/span>-Algorithmus den kleineren der beiden Typen zur\u00fcck:\u00a0<span class=\"quellcode\">std::conditional&lt;(sizeof(T1)&lt;sizeof(T2)),T1,T2&gt;::type.<\/span><\/p>\n<p><strong>Optimierung<\/strong><\/p>\n<p>Code zu schreiben, der sich beim \u00dcbersetzen selbst optimiert, das erlaubt die Type-Traits Bibliothek. So enth\u00e4lt die Standard Template Library (STL) optimierte Versionen der bekannten Algorithmen\u00a0<span class=\"quellcode\">std::copy, std::fill oder std::equal.\u00a0<\/span><\/p>\n<p>Die Idee ist recht einfach. Immer, wenn die Algorithmen auf Container agieren, deren Elemente hinreichend einfach sind, kommt ein optimierter Algorithmus zum Einsatz. Damit ist es m\u00f6glich, die Elemente nicht elementweise zu kopieren (<span class=\"quellcode\">std::copy<\/span>), zu f\u00fcllen (<span class=\"quellcode\">std::fill<\/span>) oder zu vergleichen (<span class=\"quellcode\">std::equal<\/span>), sondern ganze Containerbereiche zu bearbeiten. Daf\u00fcr kommen die C-Funktionen\u00a0<span class=\"quellcode\">memmove<\/span>,\u00a0<span class=\"quellcode\">memset<\/span>\u00a0und\u00a0<span class=\"quellcode\">memcpy<\/span>\u00a0zum Einsatz.<\/p>\n<p>Ob die Containerelemente hinreichend einfach sind, entscheiden zur Compilezeit die Funktionen der Type-Traits Bibliothek.<\/p>\n<p class=\"quellcode\">template &lt;typename I, typename T, bool b&gt;<\/p>\n<p class=\"quellcode\">void fill_impl(I first,I last,const T&amp; val,<\/p>\n<p class=\"quellcode\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const std::integral_constant&lt;bool, b&gt;&amp;){<\/p>\n<p class=\"quellcode\">\u00a0\u00a0 while(first != last){<\/p>\n<p class=\"quellcode\">\u00a0\u00a0\u00a0 *first = val;<\/p>\n<p class=\"quellcode\">\u00a0\u00a0\u00a0 ++first;<\/p>\n<p class=\"quellcode\">\u00a0 }<\/p>\n<p class=\"quellcode\">}<\/p>\n<p class=\"quellcode\">template &lt;typename T&gt;<\/p>\n<p class=\"quellcode\">void fill_impl(T* first, T* last, const T&amp; val,\u00a0const std::true_type&amp;){<\/p>\n<p class=\"quellcode\">\u00a0\u00a0std::memset(first, val, last-first);<\/p>\n<p class=\"quellcode\">}<\/p>\n<p class=\"quellcode\">template &lt;class I, class T&gt;<\/p>\n<p class=\"quellcode\">inline void fill(I first, I last, const T&amp; val){<\/p>\n<p class=\"quellcode\">\u00a0 typedef\u00a0integral_constant&lt;bool,is_trivially_copy_assignable&lt;T&gt;::value<\/p>\n<p class=\"quellcode\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &amp;&amp; (sizeof(T) == 1)&gt; boolType;<\/p>\n<p class=\"quellcode\">\u00a0 fill_impl(first, last, val,\u00a0boolType());<\/p>\n<p class=\"quellcode\">}<\/p>\n<p>&nbsp;<\/p>\n<p>Wird\u00a0<span class=\"quellcode\">std::fill<\/span>\u00a0aufgerufen, verwendet der Compiler die Implementierungsfunktion fill_impl mit std::memset genau dann, wenn die Elemente des Containers einen vom Compiler automatisch erzeugten Kopierkonstruktor besitzen und ein Byte gro\u00df sind:\u00a0<span class=\"quellcode\">is_trivially_copy_assignable&lt;T&gt;::value &amp;&amp; (sizeof(T) == 1.<\/span><\/p>\n<p>Der Performanzunterschied ist signifikant. So wird in dem Programm ein Array mit 100.000.000 Elementen gef\u00fcllt.<\/p>\n<p>&nbsp;<\/p>\n<p class=\"quellcode\">const int arraySize = 100&#8217;000&#8217;000;<\/p>\n<p class=\"quellcode\">char charArray1[arraySize]= {0,};<\/p>\n<p class=\"quellcode\">char charArray2[arraySize]= {0,};<\/p>\n<p class=\"quellcode\">int main(){<\/p>\n<p class=\"quellcode\">\u00a0 auto begin= std::chrono::system_clock::now();<\/p>\n<p class=\"quellcode\">\u00a0\u00a0fill(charArray1, charArray1 + arraySize,1);<\/p>\n<p class=\"quellcode\">\u00a0 auto last= std::chrono::system_clock::now() &#8211; begin;<\/p>\n<p class=\"quellcode\">\u00a0 cout &lt;&lt; &#8222;charArray1: &#8220; &lt;&lt; duration&lt;double&gt;(last).count() &lt;&lt; &#8220; seconds&#8220;;<\/p>\n<p class=\"quellcode\">\u00a0 begin= std::chrono::system_clock::now();<\/p>\n<p class=\"quellcode\">\u00a0\u00a0fill(charArray2, charArray2 + arraySize, static_cast&lt;char&gt;(1));<\/p>\n<p class=\"quellcode\">\u00a0 last= std::chrono::system_clock::now() &#8211; begin;<\/p>\n<p class=\"quellcode\">\u00a0 cout &lt;&lt; &#8222;charArray2: &#8220; &lt;&lt; duration&lt;double&gt;(last).count() &lt;&lt; &#8220; seconds&#8220;;<\/p>\n<p class=\"quellcode\">}<\/p>\n<p>&nbsp;<\/p>\n<p>W\u00e4hrend die Elemente des\u00a0<span class=\"quellcode\">charArray1<\/span>\u00a0mit der Zahl 1 initialisiert werden, die in der Regel 4 oder 8 Byte gro\u00dfe ist, wird charArray2 mit einer char initialisiert:\u00a0<span class=\"quellcode\">static_cast&lt;char&gt;(1). \u00a0<\/span><\/p>\n<p>Die performante Version des Algorithmus ist um den Faktor 20 schneller (siehe Abbildung,\u00a0<a title=\"Programmierung zur Compilezeit (PDF)\" href=\"https:\/\/www.microconsult.de\/wp-content\/uploads\/2025\/11\/fachinfo_ese_echt_programmierung_zur_compilzeit_grimm.pdf\" target=\"_blank\" rel=\"noopener\">PDF-Datei<\/a>).<\/p>\n<p><strong>Konstante Ausdr\u00fccke<\/strong><\/p>\n<p>Konstante Ausdr\u00fccke k\u00f6nnen zur Compilezeit evaluiert und im ROM gespeichert werden. Sie geben dem Compiler tiefen Einblick in den Sourcecode und sind implizit threadsicher.<\/p>\n<p>Konstante Ausdr\u00fccke gibt es als Variablen, benutzerdefinierte Typen und Funktionen. Im Gegensatz zu Template-Metaprogrammierung erlauben sie das Programmieren zur Compilzeit im imperativen Stil. Damit konstante Ausdr\u00fccke zur Compilezeit evaluiert werden k\u00f6nnen, gilt es ein paar Regeln zu beachten.<\/p>\n<ul>\n<li>Variablen sind implizit\u00a0<span class=\"quellcode\">const<\/span>\u00a0und m\u00fcssen durch konstante Ausdr\u00fccke initialisiert werden:\u00a0<span class=\"quellcode\">constexpr double pi= 3.14;<\/span><\/li>\n<li>Benutzerdefinierte Typen k\u00f6nnen keine virtuelle Basisklasse besitzen. Ihr Konstruktor muss vom Compiler erzeugt werden und selbst ein konstanter Ausdruck sein. Methoden, die Objekte von benutzerdefinierten Typen verwenden, m\u00fcssen konstante Ausdr\u00fccke und k\u00f6nnen nicht virtuell sein.<\/li>\n<li>Funktionen k\u00f6nnen keine statische und\u00a0<span class=\"quellcode\">thread_local<\/span>\u00a0Variablen enthalten<\/li>\n<\/ul>\n<p>Die\u00a0<span class=\"quellcode\">gcd<\/span>-Funktion ist ein konstanter Ausdruck. Sind ihre Argumente auch konstante Ausdr\u00fccke, kann sie zur Compilezeit evaluiert werden. Genau das zeigt das folgende Program:<\/p>\n<p class=\"quellcode\">#include &lt;iostream&gt;<\/p>\n<p class=\"quellcode\">constexpr auto gcd(int a, int b){<\/p>\n<p class=\"quellcode\">\u00a0 while (b != 0){<\/p>\n<p class=\"quellcode\">\u00a0\u00a0\u00a0 auto t= b;<\/p>\n<p class=\"quellcode\">\u00a0\u00a0\u00a0 b= a % b;<\/p>\n<p class=\"quellcode\">\u00a0\u00a0\u00a0 a= t;<\/p>\n<p class=\"quellcode\">\u00a0 }<\/p>\n<p class=\"quellcode\">\u00a0 return a;<\/p>\n<p class=\"quellcode\">}<\/p>\n<p class=\"quellcode\">int main(){<\/p>\n<p class=\"quellcode\">\u00a0 constexpr int i= gcd(11,121);<\/p>\n<p class=\"quellcode\">\u00a0 std::cout &lt;&lt; i &lt;&lt; std::endl;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ 11<\/p>\n<p class=\"quellcode\">\u00a0 constexpr int j= gcd(100,1000);<\/p>\n<p class=\"quellcode\">\u00a0 std::cout &lt;&lt; j &lt;&lt; std::endl;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ 100<\/p>\n<p class=\"quellcode\">}<\/p>\n<\/div>\n<div><\/div>\n<div>Ein tiefer Blick in den Objektcode zeigt, dass die Ergebnisse der\u00a0<span class=\"quellcode\">gcd<\/span>-Aufrufe bereits zur Compilezeit vorliegen:<\/div>\n<div><\/div>\n<div class=\"quellcode\">\n<p>mov\u00a0$0xb,%esi<\/p>\n<p>mov $0x601080,%edi<\/p>\n<p>&#8230;<\/p>\n<p>mov\u00a0$0x64,%esi<\/p>\n<p>mov $0x601080,%edi<\/p>\n<p>&#8230;<\/p>\n<\/div>\n<div><strong>Konstante Ausdr\u00fccke versus Template-Metaprogrammierung<\/strong><\/div>\n<div><\/div>\n<div>constexpr-Funktionen unterscheiden sich im Detail deutlich von Metafunktionen, die bei der Template-Metaprogrammierung zum Einsatz kommen. So k\u00f6nnen konstante Ausdr\u00fccke zur Compile- und Laufzeit ausgef\u00fchrt werden, Sprung- und Iterationsanweisungen sowie auch bedingte Anweisungen enthalten. Dar\u00fcber hinaus unterst\u00fctzen constexpr-Funktionen das Ver\u00e4ndern von Daten und das Arbeiten mit Flie\u00dfkommazahlen.<\/div>\n<div><\/div>\n<div><strong>Programmierung zur Compilezeit als m\u00e4chtiges Werkzeug<\/strong><\/div>\n<div><\/div>\n<div>Template-Metaprogrammierung, die Type-Traits Bibliothek und konstante Ausdr\u00fccke haben gemein, dass sie zu Compilezeit ausgef\u00fchrt werden. W\u00e4hrend Template-Metaprogrammierung aber ein tiefes Verst\u00e4ndnis von rein funktionaler Programmierung voraussetzt, ist der Einsatz der neuen C++11 Type-Traits Bibliothek deutlich intuitiver f\u00fcr den imperativ geschulten Programmierer. Nur die Namenskonventionen erinnern an Template-Metaprogrammierung. Konstante Ausdr\u00fccke mit dem C++14-Standard erlauben direkt das Programmieren im imperativen Stil.<\/div>\n<div><\/div>\n<div><strong>Weiterf\u00fchrende Informationen<\/strong><\/div>\n<div>\n<p>[1]\u00a0<a href=\"https:\/\/de.wikipedia.org\/wiki\/Turing-Vollst%C3%A4ndigkeit\" target=\"_blank\" rel=\"noopener\">Turing-Vollst\u00e4ndigkei<\/a>t<\/p>\n<p>[2]\u00a0<a href=\"https:\/\/www.boost.org\/\" target=\"_blank\" rel=\"noopener\">Boost-Bibliothek<\/a><\/p>\n<p>Rainer Grimm, &#8222;C++11 f\u00fcr Programmierer&#8220;, O\u2019Reilly 2013<\/p>\n<p>Rainer Grimm, &#8222;Modernes C++ in der Praxis&#8220;, Serie im Linux-Magazin<\/p>\n<\/div>\n<div><\/div>\n<div><a title=\"Programmierung zur Compilezeit (PDF)\" href=\"https:\/\/www.microconsult.de\/wp-content\/uploads\/2025\/11\/fachinfo_ese_echt_programmierung_zur_compilzeit_grimm.pdf\" target=\"_blank\" rel=\"noopener\"><strong>Beitrag als PDF-Datei herunterladen<\/strong><\/a><\/div>\n<hr \/>\n<h2>Echtzeit &#8211; MicroConsult Trainings &amp; Coachings<\/h2>\n<p><strong>Wollen Sie sich auf den aktuellen Stand der Technik bringen?<\/strong><\/p>\n<p>Dann informieren Sie sich\u00a0<a title=\"Alle Trainings und Termine\" href=\"https:\/\/www.microconsult.de\/alle-trainings-termine-komplettuebersicht\/\" target=\"_blank\" rel=\"noopener\"><strong>hier<\/strong>\u00a0<\/a>zu Schulungen\/ Seminaren\/ Trainings\/ Workshops und individuellen Coachings von MircoConsult zum Thema Embedded- und Echtzeit-Softwareentwicklung.<\/p>\n<p><strong>Training &amp; Coaching zu den weiteren Themen unseren Portfolios finden Sie <a title=\"Training &amp; Beratung - alle Themen\" href=\"https:\/\/www.microconsult.de\/training-beratung\/\" target=\"_blank\" rel=\"noopener\">hier<\/a>.<\/strong><\/p>\n<hr \/>\n<h2>Echtzeit &#8211; Fachwissen<\/h2>\n<p>Wertvolles Fachwissen zum Thema\u00a0Architektur \/Embedded- und Echtzeit-Softwareentwicklung steht\u00a0<a title=\"Embedded Software Architektur Fachwissen\" href=\"https:\/\/www.microconsult.de\/die-7-wichtigsten-tipps-fuer-ihre-embedded-software-architektur\/\" target=\"_blank\" rel=\"noopener\"><strong>hier<\/strong><\/a>\u00a0f\u00fcr Sie zum kostenfreien Download bereit.<\/p>\n<p><a title=\"Embedded Software Architektur Fachwissen\" href=\"https:\/\/www.microconsult.de\/die-7-wichtigsten-tipps-fuer-ihre-embedded-software-architektur\/\" target=\"_blank\" rel=\"noopener\"><strong>Zu den Fachinformationen<\/strong><\/a><\/p>\n<p><strong>Fachwissen zu weiteren Themen unseren Portfolios finden Sie <a title=\"Fachinformationen\" href=\"https:\/\/www.microconsult.de\/fachwissen\/\" target=\"_blank\" rel=\"noopener\">hier<\/a>.<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Autor: Rainer Grimm Beitrag &#8211; Embedded Software Engineering Kongress 2015 Was haben klassische Template-Metaprogrammierung, die Funktionen der Type-Traits-Bibliothek und konstante Ausdr\u00fccke gemein? Sie werden alle zur Compilezeit ausgef\u00fchrt. Damit vereinen sie h\u00f6here Performanz mit erweiterter Funktionalit\u00e4t. H\u00f6here Performanz, da Berechnungen zur Lauf- auf die Compilezeit verlegt werden. Erweiterte Funktionalit\u00e4t, da Programmierung zur Compilezeit den resultierenden [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","inline_featured_image":false,"footnotes":""},"categories":[],"tags":[],"class_list":["post-8030","post","type-post","status-publish","format-standard","hentry"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.9 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Programmierung zur Compilezeit - MicroConsult Academy GmbH<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.microconsult.de\/en\/programming-at-compile-time\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Programmierung zur Compilezeit - MicroConsult Academy GmbH\" \/>\n<meta property=\"og:description\" content=\"Autor: Rainer Grimm Beitrag &#8211; Embedded Software Engineering Kongress 2015 Was haben klassische Template-Metaprogrammierung, die Funktionen der Type-Traits-Bibliothek und konstante Ausdr\u00fccke gemein? Sie werden alle zur Compilezeit ausgef\u00fchrt. Damit vereinen sie h\u00f6here Performanz mit erweiterter Funktionalit\u00e4t. H\u00f6here Performanz, da Berechnungen zur Lauf- auf die Compilezeit verlegt werden. Erweiterte Funktionalit\u00e4t, da Programmierung zur Compilezeit den resultierenden [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.microconsult.de\/en\/programming-at-compile-time\/\" \/>\n<meta property=\"og:site_name\" content=\"MicroConsult Academy GmbH\" \/>\n<meta property=\"article:published_time\" content=\"2025-11-29T08:10:33+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-02-11T04:58:04+00:00\" \/>\n<meta name=\"author\" content=\"weissblau media\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"weissblau media\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.microconsult.de\\\/programmierung-zur-compilezeit\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.microconsult.de\\\/programmierung-zur-compilezeit\\\/\"},\"author\":{\"name\":\"weissblau media\",\"@id\":\"https:\\\/\\\/www.microconsult.de\\\/#\\\/schema\\\/person\\\/b6d4c4ae959b068fbe8d9416ed019a0a\"},\"headline\":\"Programmierung zur Compilezeit\",\"datePublished\":\"2025-11-29T08:10:33+00:00\",\"dateModified\":\"2026-02-11T04:58:04+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.microconsult.de\\\/programmierung-zur-compilezeit\\\/\"},\"wordCount\":1756,\"commentCount\":0,\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.microconsult.de\\\/programmierung-zur-compilezeit\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.microconsult.de\\\/programmierung-zur-compilezeit\\\/\",\"url\":\"https:\\\/\\\/www.microconsult.de\\\/programmierung-zur-compilezeit\\\/\",\"name\":\"Programmierung zur Compilezeit - MicroConsult Academy GmbH\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.microconsult.de\\\/#website\"},\"datePublished\":\"2025-11-29T08:10:33+00:00\",\"dateModified\":\"2026-02-11T04:58:04+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.microconsult.de\\\/#\\\/schema\\\/person\\\/b6d4c4ae959b068fbe8d9416ed019a0a\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.microconsult.de\\\/programmierung-zur-compilezeit\\\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.microconsult.de\\\/programmierung-zur-compilezeit\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.microconsult.de\\\/programmierung-zur-compilezeit\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.microconsult.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Programmierung zur Compilezeit\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.microconsult.de\\\/#website\",\"url\":\"https:\\\/\\\/www.microconsult.de\\\/\",\"name\":\"MicroConsult Academy GmbH\",\"description\":\"Professionelle Schulungen, Beratung und Projektunterst\u00fctzung\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.microconsult.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.microconsult.de\\\/#\\\/schema\\\/person\\\/b6d4c4ae959b068fbe8d9416ed019a0a\",\"name\":\"weissblau media\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/bbb409da4970da9446f6c49465d453cb8a0dae301e4d4f465b5c4e62408daa2e?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/bbb409da4970da9446f6c49465d453cb8a0dae301e4d4f465b5c4e62408daa2e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/bbb409da4970da9446f6c49465d453cb8a0dae301e4d4f465b5c4e62408daa2e?s=96&d=mm&r=g\",\"caption\":\"weissblau media\"},\"sameAs\":[\"https:\\\/\\\/www.microconsult.de\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Compile-time programming - MicroConsult Academy GmbH","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.microconsult.de\/en\/programming-at-compile-time\/","og_locale":"en_GB","og_type":"article","og_title":"Programmierung zur Compilezeit - MicroConsult Academy GmbH","og_description":"Autor: Rainer Grimm Beitrag &#8211; Embedded Software Engineering Kongress 2015 Was haben klassische Template-Metaprogrammierung, die Funktionen der Type-Traits-Bibliothek und konstante Ausdr\u00fccke gemein? Sie werden alle zur Compilezeit ausgef\u00fchrt. Damit vereinen sie h\u00f6here Performanz mit erweiterter Funktionalit\u00e4t. H\u00f6here Performanz, da Berechnungen zur Lauf- auf die Compilezeit verlegt werden. Erweiterte Funktionalit\u00e4t, da Programmierung zur Compilezeit den resultierenden [&hellip;]","og_url":"https:\/\/www.microconsult.de\/en\/programming-at-compile-time\/","og_site_name":"MicroConsult Academy GmbH","article_published_time":"2025-11-29T08:10:33+00:00","article_modified_time":"2026-02-11T04:58:04+00:00","author":"weissblau media","twitter_card":"summary_large_image","twitter_misc":{"Written by":"weissblau media","Estimated reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.microconsult.de\/programmierung-zur-compilezeit\/#article","isPartOf":{"@id":"https:\/\/www.microconsult.de\/programmierung-zur-compilezeit\/"},"author":{"name":"weissblau media","@id":"https:\/\/www.microconsult.de\/#\/schema\/person\/b6d4c4ae959b068fbe8d9416ed019a0a"},"headline":"Programmierung zur Compilezeit","datePublished":"2025-11-29T08:10:33+00:00","dateModified":"2026-02-11T04:58:04+00:00","mainEntityOfPage":{"@id":"https:\/\/www.microconsult.de\/programmierung-zur-compilezeit\/"},"wordCount":1756,"commentCount":0,"inLanguage":"en-GB","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.microconsult.de\/programmierung-zur-compilezeit\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.microconsult.de\/programmierung-zur-compilezeit\/","url":"https:\/\/www.microconsult.de\/programmierung-zur-compilezeit\/","name":"Compile-time programming - MicroConsult Academy GmbH","isPartOf":{"@id":"https:\/\/www.microconsult.de\/#website"},"datePublished":"2025-11-29T08:10:33+00:00","dateModified":"2026-02-11T04:58:04+00:00","author":{"@id":"https:\/\/www.microconsult.de\/#\/schema\/person\/b6d4c4ae959b068fbe8d9416ed019a0a"},"breadcrumb":{"@id":"https:\/\/www.microconsult.de\/programmierung-zur-compilezeit\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.microconsult.de\/programmierung-zur-compilezeit\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.microconsult.de\/programmierung-zur-compilezeit\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.microconsult.de\/"},{"@type":"ListItem","position":2,"name":"Programmierung zur Compilezeit"}]},{"@type":"WebSite","@id":"https:\/\/www.microconsult.de\/#website","url":"https:\/\/www.microconsult.de\/","name":"MicroConsult Academy GmbH","description":"Professional training, consulting and project support","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.microconsult.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":"Person","@id":"https:\/\/www.microconsult.de\/#\/schema\/person\/b6d4c4ae959b068fbe8d9416ed019a0a","name":"weissblau media","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/secure.gravatar.com\/avatar\/bbb409da4970da9446f6c49465d453cb8a0dae301e4d4f465b5c4e62408daa2e?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/bbb409da4970da9446f6c49465d453cb8a0dae301e4d4f465b5c4e62408daa2e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/bbb409da4970da9446f6c49465d453cb8a0dae301e4d4f465b5c4e62408daa2e?s=96&d=mm&r=g","caption":"weissblau media"},"sameAs":["https:\/\/www.microconsult.de"]}]}},"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/www.microconsult.de\/en\/wp-json\/wp\/v2\/posts\/8030","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.microconsult.de\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.microconsult.de\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.microconsult.de\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.microconsult.de\/en\/wp-json\/wp\/v2\/comments?post=8030"}],"version-history":[{"count":7,"href":"https:\/\/www.microconsult.de\/en\/wp-json\/wp\/v2\/posts\/8030\/revisions"}],"predecessor-version":[{"id":11620,"href":"https:\/\/www.microconsult.de\/en\/wp-json\/wp\/v2\/posts\/8030\/revisions\/11620"}],"wp:attachment":[{"href":"https:\/\/www.microconsult.de\/en\/wp-json\/wp\/v2\/media?parent=8030"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.microconsult.de\/en\/wp-json\/wp\/v2\/categories?post=8030"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.microconsult.de\/en\/wp-json\/wp\/v2\/tags?post=8030"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}