{"id":5608,"date":"2019-01-03T09:02:40","date_gmt":"2019-01-03T09:02:40","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-rules-for-template-metaprogramming\/"},"modified":"2023-06-26T10:16:39","modified_gmt":"2023-06-26T10:16:39","slug":"c-core-guidelines-rules-for-template-metaprogramming","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-rules-for-template-metaprogramming\/","title":{"rendered":"C++ Core Guidelines: Rules for Template Metaprogramming"},"content":{"rendered":"<p>Yes, you read it correctly. Today, I write about template metaprogramming, programming with types and not values.&nbsp;<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5602\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/01\/dinosaur-966869_1280.jpg\" alt=\"dinosaur 966869 1280\" width=\"400\" height=\"534\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/01\/dinosaur-966869_1280.jpg 960w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/01\/dinosaur-966869_1280-225x300.jpg 225w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/01\/dinosaur-966869_1280-768x1024.jpg 768w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>The introduction to template metaprogramming in the guidelines ends uniquely: &#8220;The syntax and techniques needed are pretty horrendous.&#8221;. In accordance, the rules are primarily about dont&#8217;s and do not provide much content:<\/p>\n<ul>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-metameta\">T.120: Use template metaprogramming only when you really need to<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-emulate\">T.121: Use template metaprogramming primarily to emulate concepts<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-tmp\">T.122: Use templates (usually template aliases) to compute types at compile time<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-fct\">T.123: Use <code class=\"highlighter-rouge no-highlight\">constexpr<\/code> functions to compute values at compile time<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-std-tmp\">T.124: Prefer to use standard-library TMP facilities<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-lib\">T.125: If you need to go beyond the standard-library TMP facilities, use an existing library<\/a><\/li>\n<\/ul>\n<p>Honestly, I don&#8217;t think template metaprogramming is so horrendous, but the syntax still has a lot of potential.<\/p>\n<p>Let me try to demystify template metaprogramming and write about programming at compile time in general. During this introduction to programming at compile time, I explicitly write about type-traits (<a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-std-tmp\">T.124: Prefer to use standard-library TMP facilities) <\/a>and <span style=\"font-family: courier new, courier;\">constexpr<\/span> functions (<a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-fct\">T.123: Use <code class=\"highlighter-rouge no-highlight\">constexpr<\/code> functions to compute values at compile time<\/a>) and implicitly refer to the other rules. Here is my plan:<\/p>\n<p>I introduce template metaprogramming, show how the type-traits library allows you to use template metaprogramming in a well-structured and portable way, and how you can use <span style=\"font-family: courier new, courier;\">constexpr<\/span> functions to replace template metaprogramming magic with ordinary functions.<\/p>\n<h2>Template Metaprogramming<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5603\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/01\/OverviewTemplateMetaprogramming.png\" alt=\"OverviewTemplateMetaprogramming\" width=\"300\" height=\"234\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/01\/OverviewTemplateMetaprogramming.png 679w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/01\/OverviewTemplateMetaprogramming-300x234.png 300w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<h3>How it all started<\/h3>\n<p>1994 presented <a href=\"http:\/\/www.erwin-unruh.de\/primorig.html\">Erwin Unruh<\/a> at a C++ committee meeting, a program that didn&#8217;t compile. Here is probably the most famous program that was never compiled.<\/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 have a look at the error messages.<\/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 30 prime numbers. 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 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 start traditional.<\/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: 0; 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> std<span style=\"color: #555555;\">::<\/span>endl;\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> std<span style=\"color: #555555;\">::<\/span>endl;    <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> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The call <span style=\"font-family: courier new, courier;\">factorial&lt;5&gt;:<\/span>:<span style=\"font-family: 'courier new', courier;\">value<\/span> in line (1) causes the instantiation of the primary or general template in line (2). During this instantiation, <span style=\"font-family: courier new, courier;\">Factorial&lt;4&gt;:<\/span>:value will be instantiated. This recursion will end if the fully specialised class template <span style=\"font-family: courier new, courier;\">Factorial&lt;1&gt;<\/span> 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><span class=\"tlid-translation translation\"><span class=\"\" title=\"\">Damn, I almost forgot to prove that the values were calculated at compile time.<\/span><\/span> Here we are with the <a href=\"https:\/\/godbolt.org\/\">Compiler Explorer<\/a>. For simplicity reasons, I only provide a screenshot of the main program and the corresponding assembler instructions.<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5606\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/01\/goldboltSource.png\" alt=\"goldboltSource\" width=\"500\" height=\"131\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/01\/goldboltSource.png 760w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/01\/goldboltSource-300x79.png 300w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5607\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/01\/goldboltAssem.png\" alt=\"goldboltAssem\" width=\"400\" height=\"155\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/01\/goldboltAssem.png 605w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/01\/goldboltAssem-300x117.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>The first yellow line and the first purple line show it. The factorials of 5 and 10 are just constants and were calculated during compile time.&nbsp;<\/p>\n<p>The factorial program is friendly but not idiomatic for template metaprogramming.<\/p>\n<h4>Manipulating Types at Compile Time<\/h4>\n<p>Manipulating types at compile time is typically for template metaprogramming. If you don&#8217;t believe me, study<span style=\"font-family: courier new, courier;\">&nbsp;<a href=\"https:\/\/en.cppreference.com\/w\/cpp\/utility\/move\">std::move<\/a>. <\/span>Here is what <span style=\"font-family: courier new, courier;\">std:<\/span>:move is conceptionally doing:<span style=\"font-family: courier new, courier;\"><\/span><\/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: #006699; font-weight: bold;\">static_cast<\/span><span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>remove_reference<span style=\"color: #555555;\">&lt;<\/span>decltype(arg)<span style=\"color: #555555;\">&gt;::<\/span>type<span style=\"color: #555555;\">&amp;&amp;&gt;<\/span>(arg);\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Okay. <span style=\"font-family: courier new, courier;\">std::move<\/span> takes an argument<span style=\"font-family: courier new, courier;\"> arg<\/span>, deduces the type (decltype<span style=\"font-family: courier new, courier;\">(arg))<\/span> from it, removes the reference (<span style=\"font-family: courier new, courier;\">remove_reverence<\/span>), and casts it to a rvalue reference (<span style=\"font-family: courier new, courier;\">static_cast&lt;&#8230;&gt;::type&amp;&amp;&gt;<\/span>). In essence, this means that <span style=\"font-family: courier new, courier;\">std:<\/span>:move returns always a rvalue reference type and, therefore, move semantic can kick it.<\/p>\n<p>How does<span style=\"font-family: courier new, courier;\"> std::remove_reference<\/span> from the <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/header\/type_traits\">type-traits library <\/a>work? Here is a code snippet removing constness from its argument.<\/p>\n<p>&nbsp;<\/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: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T <span style=\"color: #555555;\">&gt;<\/span> \r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> removeConst{ \r\n    <span style=\"color: #006699; font-weight: bold;\">typedef<\/span> T type;               <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T <span style=\"color: #555555;\">&gt;<\/span> \r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> removeConst<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">const<\/span> T<span style=\"color: #555555;\">&gt;<\/span> { \r\n    <span style=\"color: #006699; font-weight: bold;\">typedef<\/span> T type;               <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n};\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>is_same<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, removeConst<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;::<\/span>type<span style=\"color: #555555;\">&gt;::<\/span>value;        <span style=\"color: #0099ff; font-style: italic;\">\/\/ true<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>is_same<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, removeConst<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;::<\/span>type<span style=\"color: #555555;\">&gt;::<\/span>value;  <span style=\"color: #0099ff; font-style: italic;\">\/\/ true<\/span>\r\n  \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>I implemented <span style=\"font-family: courier new, courier;\">removeConst <\/span>the way <span style=\"font-family: courier new, courier;\">std::remove_const<\/span> is probably implemented in the type-traits library. <span style=\"font-family: courier new, courier;\">std::is_same<\/span> from the type-traits library helps me to decide at compile-time if both types are the same. In the case of <span style=\"font-family: courier new, courier;\">removeConst&lt;int&gt;<\/span>, the first or general class template kicks in; in the case of<span style=\"font-family: courier new, courier;\"> removeConst&lt;const int<\/span>&gt;, the partial specialization for <span style=\"font-family: courier new, courier;\">const T<\/span> applies. The critical observation is that both class templates return the underlying type in line (1), and the constness is removed.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>In the <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-programming-at-compile-time\">next post<\/a>, I will continue my introduction to programming at compile time. This means, in particular, that I will compare functions and metafunctions before I come to the type-traits library.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Yes, you read it correctly. Today, I write about template metaprogramming, programming with types and not values.&nbsp;<\/p>\n","protected":false},"author":21,"featured_media":5602,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[435],"class_list":["post-5608","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c","tag-template-metaprogramming"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5608","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=5608"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5608\/revisions"}],"predecessor-version":[{"id":6799,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5608\/revisions\/6799"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5602"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5608"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5608"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5608"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}