{"id":6244,"date":"2021-10-26T11:47:09","date_gmt":"2021-10-26T11:47:09","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/template-metaprogramming-a-introduction\/"},"modified":"2023-06-26T09:23:51","modified_gmt":"2023-06-26T09:23:51","slug":"template-metaprogramming-a-introduction","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/template-metaprogramming-a-introduction\/","title":{"rendered":"Template Metaprogramming  &#8211; How it All Started"},"content":{"rendered":"<p>Metaprogramming is programming on programs. C++ applies metaprogramming at compile time. It started in C++98 with template metaprogramming, was formalized in C++11 with the type-traits library, and since C++11 has steadily improved. The main driving force is constant expressions. In this post, I want to write about its roots.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6240\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/TemplateMetaprogramming.png\" alt=\"TemplateMetaprogramming\" width=\"650\" height=\"403\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/TemplateMetaprogramming.png 907w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/TemplateMetaprogramming-300x186.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/TemplateMetaprogramming-768x476.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>In writing about template metaprogramming, I want to demystify its techniques. This demystification helps you to understand better the functions of the <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/header\/type_traits\">type-traits library<\/a> and, in particular, appreciate <code>constexpr<\/code>. Most of the bad reputation of template metaprogramming is that you may get error messages of epic length. Template metaprogramming was not designed; it started with an accident.<\/p>\n<h2>The Accident<\/h2>\n<p>In 1994, <a href=\"http:\/\/www.erwin-unruh.de\/primorig.html\">Erwin Unruh<\/a> from Siemens presented at a C++ committee meeting a program that didn&#8217;t compile. Here is probably the most famous program that never compiled successfully.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ Prime number computation by Erwin Unruh<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span> i<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #006699; font-weight: bold;\">struct<\/span> D { D(<span style=\"color: #007788; font-weight: bold;\">void<\/span><span style=\"color: #555555;\">*<\/span>); <span style=\"color: #006699; font-weight: bold;\">operator<\/span> <span style=\"color: #cc00ff;\">int<\/span>(); };\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span> p, <span style=\"color: #007788; font-weight: bold;\">int<\/span> i<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #006699; font-weight: bold;\">struct<\/span> is_prime {\r\n    <span style=\"color: #006699; font-weight: bold;\">enum<\/span> { prim <span style=\"color: #555555;\">=<\/span> (p<span style=\"color: #555555;\">%<\/span>i) <span style=\"color: #555555;\">&amp;&amp;<\/span> is_prime<span style=\"color: #555555;\">&lt;<\/span>(i <span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #ff6600;\">2<\/span> <span style=\"color: #555555;\">?<\/span> p <span style=\"color: #555555;\">:<\/span> <span style=\"color: #ff6600;\">0<\/span>), i <span style=\"color: #555555;\">-<\/span><span style=\"color: #ff6600;\">1<\/span><span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #555555;\">::<\/span> prim };\r\n    };\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span> i <span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #006699; font-weight: bold;\">struct<\/span> Prime_print {\r\n    Prime_print<span style=\"color: #555555;\">&lt;<\/span>i<span style=\"color: #555555;\">-<\/span><span style=\"color: #ff6600;\">1<\/span><span style=\"color: #555555;\">&gt;<\/span> a;\r\n    <span style=\"color: #006699; font-weight: bold;\">enum<\/span> { prim <span style=\"color: #555555;\">=<\/span> is_prime<span style=\"color: #555555;\">&lt;<\/span>i, i<span style=\"color: #555555;\">-<\/span><span style=\"color: #ff6600;\">1<\/span><span style=\"color: #555555;\">&gt;::<\/span>prim };\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">f<\/span>() { D<span style=\"color: #555555;\">&lt;<\/span>i<span style=\"color: #555555;\">&gt;<\/span> d <span style=\"color: #555555;\">=<\/span> prim; }\r\n    };\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> is_prime<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #ff6600;\">0<\/span>,<span style=\"color: #ff6600;\">0<\/span><span style=\"color: #555555;\">&gt;<\/span> { <span style=\"color: #006699; font-weight: bold;\">enum<\/span> {prim<span style=\"color: #555555;\">=<\/span><span style=\"color: #ff6600;\">1<\/span>}; };\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> is_prime<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #ff6600;\">0<\/span>,<span style=\"color: #ff6600;\">1<\/span><span style=\"color: #555555;\">&gt;<\/span> { <span style=\"color: #006699; font-weight: bold;\">enum<\/span> {prim<span style=\"color: #555555;\">=<\/span><span style=\"color: #ff6600;\">1<\/span>}; };\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> Prime_print<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #ff6600;\">2<\/span><span style=\"color: #555555;\">&gt;<\/span> { <span style=\"color: #006699; font-weight: bold;\">enum<\/span> {prim <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">1<\/span>}; <span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">f<\/span>() { D<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #ff6600;\">2<\/span><span style=\"color: #555555;\">&gt;<\/span> d <span style=\"color: #555555;\">=<\/span> prim; } };\r\n<span style=\"color: #009999;\">#ifndef LAST<\/span>\r\n<span style=\"color: #009999;\">#define LAST 10<\/span>\r\n<span style=\"color: #009999;\">#endif<\/span>\r\nmain () {\r\n    Prime_print<span style=\"color: #555555;\">&lt;<\/span>LAST<span style=\"color: #555555;\">&gt;<\/span> a;\r\n    } \r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Erwin Unruh used the Metaware Compilers, but the program is not valid for C++ anymore. A newer variant from the author is <a href=\"http:\/\/www.erwin-unruh.de\/prim.html\">here<\/a>. Okay, why is this program so famous? Let&#8217;s look at the original error messages that wrote type as txpe.<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5604\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/01\/prim.PNG\" alt=\"prim\" width=\"500\" height=\"182\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/01\/prim.PNG 864w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/01\/prim-300x109.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/01\/prim-768x280.png 768w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>I highlighted the important parts in red. I think you see the pattern. The program calculates at compile time the first prime numbers until 30. This means template instantiation can be used to do math at compile time. It is even better. Template metaprogramming is <a href=\"https:\/\/en.wikipedia.org\/wiki\/Turing_completeness\">Turing-complete<\/a>, and can, therefore, be used to solve any computational problem. (Of course, Turing completeness holds only in theory for template metaprogramming because the recursion instantiation depth (at least 1024 with C++11) and the length of the names generated during template instantiation provide some limitations.)<\/p>\n<\/p>\n<h3>How does the magic work?<\/h3>\n<p>Let me decompose what is going on step by step.<\/p>\n<h4>Calculating at Compile Time<\/h4>\n<p>Calculating the factorial of a number is the &#8220;Hello World&#8221; of template metaprogramming.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ factorial.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span> N<span style=\"color: #555555;\">&gt;<\/span>                                                                 <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> Factorial{\r\n    <span style=\"color: #006699; font-weight: bold;\">static<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #006699; font-weight: bold;\">const<\/span> value <span style=\"color: #555555;\">=<\/span> N <span style=\"color: #555555;\">*<\/span> Factorial<span style=\"color: #555555;\">&lt;<\/span>N<span style=\"color: #555555;\">-<\/span><span style=\"color: #ff6600;\">1<\/span><span style=\"color: #555555;\">&gt;::<\/span>value;\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;&gt;<\/span>                                                                      <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> Factorial<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #ff6600;\">1<\/span><span style=\"color: #555555;\">&gt;<\/span>{\r\n    <span style=\"color: #006699; font-weight: bold;\">static<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #006699; font-weight: bold;\">const<\/span> value <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">1<\/span>;\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> '\\n';\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Factorial&lt;5&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> Factorial<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #ff6600;\">5<\/span><span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&lt;&lt;<\/span> '\\n'<span style=\"color: #555555;\"><\/span>;    <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Factorial&lt;10&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> Factorial<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #ff6600;\">10<\/span><span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&lt;&lt;<\/span> '\\n'<span style=\"color: #555555;\"><\/span>;  <em><span style=\"color: #0099ff;\">\/\/ (4)<\/span><\/em>\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> '\\n'<span style=\"color: #555555;\"><\/span>;\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The call<code> factorial&lt;5&gt;::value<\/code> in line (1) causes the instantiation of the primary or general template in line (2). During this instantiation, <code>Factorial&lt;4&gt;::value<\/code> will be instantiated. This recursion will end if the fully specialized class template<code> Factorial&lt;1&gt; <\/code>kicks in in line (3).&nbsp; Maybe, you like it more pictorial.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5605\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/01\/factorial5.PNG\" alt=\"factorial5\" width=\"500\" height=\"119\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/01\/factorial5.PNG 762w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/01\/factorial5-300x72.png 300w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>Here is the output of the program:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5123\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/factorial.png\" alt=\"factorial\" width=\"300\" height=\"172\" style=\"display: block; margin-left: auto; margin-right: auto;\" \/><\/p>\n<p>Thanks to <a href=\"https:\/\/cppinsights.io\/s\/ad3d8a2a\">C++ Insights<\/a> and <a href=\"https:\/\/godbolt.org\/z\/5j11zj1ax\">Compiler Explorer<\/a>, you can and should analyze the program further. This should help to build your intuition about template instantiation and template metaprogramming.<\/p>\n<p>Let me start with C++ Insights:<\/p>\n<h4>C++ Insights<\/h4>\n<p>The call<code> Factorial&lt;5&gt;::value<\/code> (line 1) causes the instantiation of the class template for the numbers 5 to 2. The full specialization for 1 is already available. The call <code>Factorial&lt;10&gt;::value<\/code> (line 2) causes the instantiation of the function template for the numbers 10 &#8211; 6 because all other fully specialized function templates are already available. The following output shows the instantiation for the numbers 5 to 2.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6241\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/CppInsightsRecursiveInstantiaion.png\" alt=\"CppInsightsRecursiveInstantiaion\" width=\"444\" height=\"738\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/CppInsightsRecursiveInstantiaion.png 444w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/CppInsightsRecursiveInstantiaion-180x300.png 180w\" sizes=\"auto, (max-width: 444px) 100vw, 444px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p><span class=\"tlid-translation translation\"><span class=\"\" title=\"\"><\/span><\/span><\/p>\n<p>Now, my analysis continues with the <a href=\"https:\/\/godbolt.org\/z\/5j11zj1ax\">Compiler Explorer<\/a>.<\/p>\n<h4>Compiler Explorer<\/h4>\n<p>For simplicity reasons, I only provide a screenshot of the main program and the corresponding assembler instructions.<\/p>\n<p>The Compiler Explorer allows you to visualize this compile-time calculation.<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6242\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/compilerExplorerCodeFactorial.png\" alt=\"goldboltSource\" width=\"600\" height=\"180\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/compilerExplorerCodeFactorial.png 716w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/compilerExplorerCodeFactorial-300x90.png 300w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6243\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/compilerExplorerAssemblerFactorial.png\" alt=\"goldboltAssem\" width=\"662\" height=\"216\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/compilerExplorerAssemblerFactorial.png 662w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/compilerExplorerAssemblerFactorial-300x98.png 300w\" sizes=\"auto, (max-width: 662px) 100vw, 662px\" \/><\/p>\n<p>The output shows it. The factorials of 5 and 10 are just constants and were calculated during compile time. You can see the result directly in the first line and last line of the assembler instructions.<\/p>\n<h2>CppCon 2021<\/h2>\n<p>I was quite happy this week that I could use a previous post as a starting point for this post. I gave <a href=\"https:\/\/cppcon.org\/program2021\/\">this week four talks at the CppCon<\/a> and honestly, this was too much. Here are my talks that are published on <a href=\"https:\/\/www.youtube.com\/user\/CppCon\">Youtube&#8217;s CppCon channel<\/a>. The pdfs are already available.<\/p>\n<ul>\n<li><a href=\"https:\/\/www.grimm-jaud.de\/images\/stories\/pdfs\/ConcurrencyPatterns.pdf\">Concurrency Patterns<\/a><a href=\"https:\/\/cppcon.org\/program2021\/\"> <\/a><\/li>\n<li><a href=\"https:\/\/www.grimm-jaud.de\/images\/stories\/pdfs\/TheManyFlavorsOfConstnessInModernCpp.pdf\"><span class=\"css-901oao css-16my406 r-poiln3 r-bcqeeo r-qvutc0\">The Many Flavors of Constness in Modern C++<\/span><\/a><\/li>\n<li><a href=\"https:\/\/www.grimm-jaud.de\/images\/stories\/pdfs\/ObjectOrientedProgramming.pdf\"><span class=\"css-901oao css-16my406 r-poiln3 r-bcqeeo r-qvutc0\">Object-Oriented Programming: The Good Parts<\/span><\/a><\/li>\n<li><span class=\"css-901oao css-16my406 r-poiln3 r-bcqeeo r-qvutc0\"><a href=\"https:\/\/www.grimm-jaud.de\/images\/stories\/pdfs\/C20TheSmallPearls.pdf\">C++20: The Small Pearls<\/a> <br \/><\/span><\/li>\n<\/ul>\n<h2>What&#8217;s next?<\/h2>\n<p>In my next post, I will continue my journey with template metaprogramming and provide more insights.<\/p>\n<p>&nbsp;<\/p>\n<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Metaprogramming is programming on programs. C++ applies metaprogramming at compile time. It started in C++98 with template metaprogramming, was formalized in C++11 with the type-traits library, and since C++11 has steadily improved. The main driving force is constant expressions. In this post, I want to write about its roots.<\/p>\n","protected":false},"author":21,"featured_media":6240,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[376],"tags":[435],"class_list":["post-6244","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-templates","tag-template-metaprogramming"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6244","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=6244"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6244\/revisions"}],"predecessor-version":[{"id":6694,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6244\/revisions\/6694"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/6240"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=6244"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=6244"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=6244"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}