{"id":5657,"date":"2019-03-28T06:17:25","date_gmt":"2019-03-28T06:17:25","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-insights-template-instantiation\/"},"modified":"2019-03-28T06:17:25","modified_gmt":"2019-03-28T06:17:25","slug":"c-insights-template-instantiation","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-insights-template-instantiation\/","title":{"rendered":"C++ Insights &#8211; Template Instantiation"},"content":{"rendered":"<p>Today&#8217;s post from Andreas is about template instantiation. C++ Insights helps you a lot to get a deeper insight into this automatic process.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5656\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/03\/03-template-instantiation.png\" alt=\"03 template instantiation\" width=\"600\" height=\"338\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/03\/03-template-instantiation.png 1280w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/03\/03-template-instantiation-300x169.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/03\/03-template-instantiation-1024x576.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/03\/03-template-instantiation-768x432.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>The future of C++ speaks templates. It is, therefore, a good idea to get a better view of templates.<\/p>\n<h2>Template Instantiation<\/h2>\n<p>I\u2019d like to start with a disclaimer at this point. There are other tools to do this job. I saw a preview of Visual Studio which can show you the instantiated template. The same applies to cevelop. It\u2019s not an unique feature that C++ Insights provides here. Except for one difference: it shows you the transformations for all the code you type in at once. Everything! Not just templates.<\/p>\n<p>What I\u2019m talking about is a situation I believe many of us had at least once. There is this function template, a bigger one. We\u2019d like to know for which types it gets instantiated and from where. An easy thing for C++ Insights, the compiler must know this and so does C++ Insights.<\/p>\n<p>Being able to show the code, which effectively runs, is valuable while teaching. I experienced that it helped students a lot if they could see what is going on rather than have to believe me.<\/p>\n<\/p>\n<h3>The Laziness of Template Instantiation<\/h3>\n<p>One nice thing C++ Insights shows you is what it doesn\u2019t show. The compiler, at least Clang in which C++ Insights runs, is eager to give us the most efficient code. When it comes to templates, the compiler generates code only for functions or methods which are actually used. You can have a class template with a certain method which is never called. Like here:<\/p>\n<pre><code class=\"language-C++\"><span class=\"hljs-keyword\">template<\/span>&lt;<span class=\"hljs-keyword\">typename<\/span> T&gt;\r\n<span class=\"hljs-keyword\">class<\/span> Apple\r\n{\r\n<span class=\"hljs-keyword\">public<\/span>:\r\n  Apple() = <span class=\"hljs-keyword\">default<\/span>;\r\n  \r\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">bool<\/span> <span class=\"hljs-title\">IsGreen<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">const<\/span> <\/span>{ <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">false<\/span>; }\r\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">bool<\/span> <span class=\"hljs-title\">IsRed<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">const<\/span> <\/span>{ <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">true<\/span>; }\r\n};\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span>\r\n<\/span>{\r\n  Apple&lt;<span class=\"hljs-keyword\">int<\/span>&gt; apple;\r\n  \r\n  <span class=\"hljs-keyword\">if<\/span>( apple.IsRed()) {}\r\n}\r\n<\/code><\/pre>\n<p>In this case, the compiler doesn\u2019t generate the method body of that instantiation (Apple&lt;int&gt;) as you can see in <a href=\"https:\/\/cppinsights.io\/lnk?code=dGVtcGxhdGU8dHlwZW5hbWUgVD4KY2xhc3MgQXBwbGUKewpwdWJsaWM6CiAgQXBwbGUoKSA9IGRlZmF1bHQ7CiAgCiAgYm9vbCBJc0dyZWVuKCkgY29uc3QgeyByZXR1cm4gZmFsc2U7IH0KICBib29sIElzUmVkKCkgY29uc3QgeyByZXR1cm4gdHJ1ZTsgfQp9OwoKaW50IG1haW4oKQp7CiAgQXBwbGU8aW50PiBhcHBsZTsKfQ==&amp;std=cpp17&amp;rev=1.0\">C++ Insights<\/a>:<\/p>\n<pre><code class=\"language-C++\"><span class=\"hljs-keyword\">template<\/span>&lt;<span class=\"hljs-keyword\">typename<\/span> T&gt;\r\n<span class=\"hljs-keyword\">class<\/span> Apple\r\n{\r\n<span class=\"hljs-keyword\">public<\/span>:\r\n  Apple() = <span class=\"hljs-keyword\">default<\/span>;\r\n  \r\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">bool<\/span> <span class=\"hljs-title\">IsGreen<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">const<\/span> <\/span>{ <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">false<\/span>; }\r\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">bool<\/span> <span class=\"hljs-title\">IsRed<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">const<\/span> <\/span>{ <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">true<\/span>; }\r\n};\r\n\r\n<span class=\"hljs-comment\">\/* First instantiated from: insights.cpp:13 *\/<\/span>\r\n<span class=\"hljs-preprocessor\">#<span class=\"hljs-keyword\">ifdef<\/span> INSIGHTS_USE_TEMPLATE<\/span>\r\n<span class=\"hljs-keyword\">template<\/span>&lt;&gt;\r\n<span class=\"hljs-keyword\">class<\/span> Apple&lt;<span class=\"hljs-keyword\">int<\/span>&gt;\r\n{  \r\n  <span class=\"hljs-keyword\">public<\/span>: \r\n  <span class=\"hljs-comment\">\/\/ inline constexpr Apple() noexcept = default;<\/span>\r\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">inline<\/span> <span class=\"hljs-keyword\">bool<\/span> <span class=\"hljs-title\">IsGreen<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">const<\/span><\/span>;\r\n  \r\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">inline<\/span> <span class=\"hljs-keyword\">bool<\/span> <span class=\"hljs-title\">IsRed<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">const<\/span><\/span>;\r\n  \r\n  <span class=\"hljs-comment\">\/\/ inline constexpr Apple(const Apple&lt;int&gt; &amp;) = default;<\/span>\r\n  <span class=\"hljs-comment\">\/\/ inline constexpr Apple(Apple&lt;int&gt; &amp;&amp;) = default;<\/span>\r\n};\r\n\r\n<span class=\"hljs-preprocessor\">#<span class=\"hljs-keyword\">endif<\/span><\/span>\r\n\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span>\r\n<\/span>{\r\n  Apple&lt;<span class=\"hljs-keyword\">int<\/span>&gt; apple = Apple&lt;<span class=\"hljs-keyword\">int<\/span>&gt;();\r\n}\r\n<\/code><\/pre>\n<p>Even if the method is used with a different instantiation (<code>Apple&lt;char&gt;<\/code>), there will be no code for the int variant. Of course, the method is present for <code>Apple&lt;char&gt;<\/code>. See for yourself in <a href=\"https:\/\/cppinsights.io\/lnk?code=dGVtcGxhdGU8dHlwZW5hbWUgVD4KY2xhc3MgQXBwbGUKewpwdWJsaWM6CiAgQXBwbGUoKSA9IGRlZmF1bHQ7CiAgCiAgYm9vbCBJc0dyZWVuKCkgY29uc3QgeyByZXR1cm4gZmFsc2U7IH0KICBib29sIElzUmVkKCkgY29uc3QgeyByZXR1cm4gdHJ1ZTsgfQp9OwoKaW50IG1haW4oKQp7CiAgQXBwbGU8aW50PiBhcHBsZTsKICBBcHBsZTxjaGFyPiBjQXBwbGU7CiAgCiAgY0FwcGxlLklzR3JlZW4oKTsKfQ==&amp;std=cpp17&amp;rev=1.0\">C++ Insights<\/a>:<\/p>\n<pre><code class=\"language-C++\"><span class=\"hljs-keyword\">template<\/span>&lt;<span class=\"hljs-keyword\">typename<\/span> T&gt;\r\n<span class=\"hljs-keyword\">class<\/span> Apple\r\n{\r\n<span class=\"hljs-keyword\">public<\/span>:\r\n  Apple() = <span class=\"hljs-keyword\">default<\/span>;\r\n  \r\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">bool<\/span> <span class=\"hljs-title\">IsGreen<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">const<\/span> <\/span>{ <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">false<\/span>; }\r\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">bool<\/span> <span class=\"hljs-title\">IsRed<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">const<\/span> <\/span>{ <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">true<\/span>; }\r\n};\r\n\r\n<span class=\"hljs-comment\">\/* First instantiated from: insights.cpp:13 *\/<\/span>\r\n<span class=\"hljs-preprocessor\">#<span class=\"hljs-keyword\">ifdef<\/span> INSIGHTS_USE_TEMPLATE<\/span>\r\n<span class=\"hljs-keyword\">template<\/span>&lt;&gt;\r\n<span class=\"hljs-keyword\">class<\/span> Apple&lt;<span class=\"hljs-keyword\">int<\/span>&gt;\r\n{  \r\n  <span class=\"hljs-keyword\">public<\/span>: \r\n  <span class=\"hljs-comment\">\/\/ inline constexpr Apple() noexcept = default;<\/span>\r\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">inline<\/span> <span class=\"hljs-keyword\">bool<\/span> <span class=\"hljs-title\">IsGreen<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">const<\/span><\/span>;\r\n  \r\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">inline<\/span> <span class=\"hljs-keyword\">bool<\/span> <span class=\"hljs-title\">IsRed<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">const<\/span><\/span>;\r\n  \r\n  <span class=\"hljs-comment\">\/\/ inline constexpr Apple(const Apple&lt;int&gt; &amp;) = default;<\/span>\r\n  <span class=\"hljs-comment\">\/\/ inline constexpr Apple(Apple&lt;int&gt; &amp;&amp;) = default;<\/span>\r\n};\r\n\r\n<span class=\"hljs-preprocessor\">#<span class=\"hljs-keyword\">endif<\/span><\/span>\r\n\r\n\r\n<span class=\"hljs-comment\">\/* First instantiated from: insights.cpp:14 *\/<\/span>\r\n<span class=\"hljs-preprocessor\">#<span class=\"hljs-keyword\">ifdef<\/span> INSIGHTS_USE_TEMPLATE<\/span>\r\n<span class=\"hljs-keyword\">template<\/span>&lt;&gt;\r\n<span class=\"hljs-keyword\">class<\/span> Apple&lt;<span class=\"hljs-keyword\">char<\/span>&gt;\r\n{  \r\n  <span class=\"hljs-keyword\">public<\/span>: \r\n  <span class=\"hljs-comment\">\/\/ inline constexpr Apple() noexcept = default;<\/span>\r\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">inline<\/span> <span class=\"hljs-keyword\">bool<\/span> <span class=\"hljs-title\">IsGreen<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">const<\/span>\r\n  <\/span>{\r\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">false<\/span>;\r\n  }\r\n  \r\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">inline<\/span> <span class=\"hljs-keyword\">bool<\/span> <span class=\"hljs-title\">IsRed<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">const<\/span><\/span>;\r\n  \r\n  <span class=\"hljs-comment\">\/\/ inline constexpr Apple(const Apple&lt;char&gt; &amp;) = default;<\/span>\r\n  <span class=\"hljs-comment\">\/\/ inline constexpr Apple(Apple&lt;char&gt; &amp;&amp;) = default;<\/span>\r\n};\r\n\r\n<span class=\"hljs-preprocessor\">#<span class=\"hljs-keyword\">endif<\/span><\/span>\r\n\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span>\r\n<\/span>{\r\n  Apple&lt;<span class=\"hljs-keyword\">int<\/span>&gt; apple = Apple&lt;<span class=\"hljs-keyword\">int<\/span>&gt;();\r\n  Apple&lt;<span class=\"hljs-keyword\">char<\/span>&gt; cApple = Apple&lt;<span class=\"hljs-keyword\">char<\/span>&gt;();\r\n  cApple.IsGreen();\r\n}\r\n<\/code><\/pre>\n<p>This is brilliant because the compiler helps us to generate small binaries. Another view is that it can help to debug, for example, which constructor is used.<\/p>\n<p>What we can also see with C++ Insights is which line in the original code caused the instantiation. This can be helpful if you do not expect a certain instantiation.<\/p>\n<h3>Class Template Argument Deduction<\/h3>\n<p>When using C++17 and CTAD (class template argument deduction) it can sometimes be less obvious what types you got. Assume this code (I know there it is probably easy to see):<\/p>\n<pre><code class=\"language-C++\"><span class=\"hljs-preprocessor\">#<span class=\"hljs-keyword\">include<\/span> <span class=\"hljs-string\">&lt;vector&gt;<\/span><\/span>\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span>\r\n<\/span>{\r\n  <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">vector<\/span> v{<span class=\"hljs-number\">1<\/span>,<span class=\"hljs-number\">2<\/span>,<span class=\"hljs-number\">3<\/span>};\r\n  <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">vector<\/span> vd{<span class=\"hljs-number\">1.0<\/span>,<span class=\"hljs-number\">2.0<\/span>,<span class=\"hljs-number\">3.0<\/span>};\r\n\r\n  <span class=\"hljs-comment\">\/\/v = vd; \/\/ does not compile<\/span>\r\n}\r\n<\/code><\/pre>\n<p>We have two std::vectors which each gets three numbers assigned. Despite the fact that these two vectors really look equal we cannot assign vd to v. It might be obvious here, v is of type int while vd is of type double. A fairly easy thing for <a href=\"https:\/\/cppinsights.io\/lnk?code=I2luY2x1ZGUgPHZlY3Rvcj4KCmludCBtYWluKCkKewogIHN0ZDo6dmVjdG9yIHZ7MSwyLDN9OwogIHN0ZDo6dmVjdG9yIHZkezEuMCwyLjAsMy4wfTsKCiAgLy92ID0gdmQ7IC8vIGRvZXMgbm90IGNvbXBpbGUKfQ==&amp;std=cpp17&amp;rev=1.0\">C++ Insights<\/a>:<\/p>\n<pre><code class=\"language-C++\"><span class=\"hljs-preprocessor\">#<span class=\"hljs-keyword\">include<\/span> <span class=\"hljs-string\">&lt;vector&gt;<\/span><\/span>\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span>\r\n<\/span>{\r\n  <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">vector<\/span>&lt;<span class=\"hljs-keyword\">int<\/span>, <span class=\"hljs-built_in\">std<\/span>::allocator&lt;<span class=\"hljs-keyword\">int<\/span>&gt; &gt; v = <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">vector<\/span>&lt;<span class=\"hljs-keyword\">int<\/span>, <span class=\"hljs-built_in\">std<\/span>::allocator&lt;<span class=\"hljs-keyword\">int<\/span>&gt; &gt;{<span class=\"hljs-built_in\">std<\/span>::initializer_list&lt;<span class=\"hljs-keyword\">int<\/span>&gt;{<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">2<\/span>, <span class=\"hljs-number\">3<\/span>}, <span class=\"hljs-built_in\">std<\/span>::allocator&lt;<span class=\"hljs-keyword\">int<\/span>&gt;()};\r\n  <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">vector<\/span>&lt;<span class=\"hljs-keyword\">double<\/span>, <span class=\"hljs-built_in\">std<\/span>::allocator&lt;<span class=\"hljs-keyword\">double<\/span>&gt; &gt; vd = <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">vector<\/span>&lt;<span class=\"hljs-keyword\">double<\/span>, <span class=\"hljs-built_in\">std<\/span>::allocator&lt;<span class=\"hljs-keyword\">double<\/span>&gt; &gt;{<span class=\"hljs-built_in\">std<\/span>::initializer_list&lt;<span class=\"hljs-keyword\">double<\/span>&gt;{<span class=\"hljs-number\">1.0<\/span>, <span class=\"hljs-number\">2.0<\/span>, <span class=\"hljs-number\">3.0<\/span>}, <span class=\"hljs-built_in\">std<\/span>::allocator&lt;<span class=\"hljs-keyword\">double<\/span>&gt;()};\r\n}\r\n<\/code><\/pre>\n<p>There you can see what type vector really has.<\/p>\n<h3><span style=\"font-family: courier new, courier;\">constexpr if<\/span><\/h3>\n<p>While we are talking about <ins>C++17, there is another new feature: <code>constexpr if<\/code>. Let\u2019s have a look at what C++<\/ins> Insights can do there for us. In the example below we have a <code>stringify <\/code>template which makes a <code>std::string<\/code> from the parameter passed to the <a href=\"https:\/\/cppinsights.io\/lnk?code=I2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPHR5cGVfdHJhaXRzPgoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnN0ZDo6c3RyaW5nIHN0cmluZ2lmeShUJiYgdCkKewogIGlmIGNvbnN0ZXhwcihzdGQ6OmlzX3NhbWVfdjxULCBzdGQ6OnN0cmluZz4pIHsKICAgIHJldHVybiB0OwogIH0gZWxzZSB7CiAgICByZXR1cm4gc3RkOjp0b19zdHJpbmcodCk7CiAgfQp9CgppbnQgbWFpbigpCnsKICBhdXRvIHggPSBzdHJpbmdpZnkoMik7CiAgYXV0byB5ID0gc3RyaW5naWZ5KHN0ZDo6c3RyaW5neyJIZWxsbyJ9KTsKfQ==&amp;std=cpp17&amp;rev=1.0\">function<\/a>:<\/p>\n<pre><code class=\"language-C++\"><span class=\"hljs-preprocessor\">#<span class=\"hljs-keyword\">include<\/span> <span class=\"hljs-string\">&lt;string&gt;<\/span><\/span>\r\n<span class=\"hljs-preprocessor\">#<span class=\"hljs-keyword\">include<\/span> <span class=\"hljs-string\">&lt;type_traits&gt;<\/span><\/span>\r\n\r\n<span class=\"hljs-keyword\">template<\/span> &lt;<span class=\"hljs-keyword\">typename<\/span> T&gt;\r\n<span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-function\"><span class=\"hljs-built_in\">string<\/span> <span class=\"hljs-title\">stringify<\/span><span class=\"hljs-params\">(T&amp;&amp; t)<\/span>\r\n<\/span>{\r\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-title\">constexpr<\/span><span class=\"hljs-params\">(<span class=\"hljs-built_in\">std<\/span>::is_same_v&lt;T, <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span>&gt;)<\/span> <\/span>{\r\n    <span class=\"hljs-keyword\">return<\/span> t;\r\n  } <span class=\"hljs-keyword\">else<\/span> {\r\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-built_in\">std<\/span>::to_string(t);\r\n  }\r\n}\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span>\r\n<\/span>{\r\n  <span class=\"hljs-keyword\">auto<\/span> x = stringify(<span class=\"hljs-number\">2<\/span>);\r\n  <span class=\"hljs-keyword\">auto<\/span> y = stringify(<span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span>{<span class=\"hljs-string\">\"Hello\"<\/span>});\r\n}\r\n<\/code><\/pre>\n<p>Of course, if we pass in a <code>std::string<\/code> it just returns this string. The <code>constexpr if<\/code> helps us to make this entire function template possible. Because there is no <code>to_string<\/code> function which takes a <code>std::string<\/code>. With a normal,&nbsp;<code>if <\/code>this code would not compile.<\/p>\n<p>Now, what happens, if we pass in a c-string? Like here:<\/p>\n<pre><code class=\"language-C++\"><span class=\"hljs-preprocessor\">#<span class=\"hljs-keyword\">include<\/span> <span class=\"hljs-string\">&lt;string&gt;<\/span><\/span>\r\n<span class=\"hljs-preprocessor\">#<span class=\"hljs-keyword\">include<\/span> <span class=\"hljs-string\">&lt;type_traits&gt;<\/span><\/span>\r\n\r\n<span class=\"hljs-keyword\">template<\/span> &lt;<span class=\"hljs-keyword\">typename<\/span> T&gt;\r\n<span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-function\"><span class=\"hljs-built_in\">string<\/span> <span class=\"hljs-title\">stringify<\/span><span class=\"hljs-params\">(T&amp;&amp; t)<\/span>\r\n<\/span>{\r\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-title\">constexpr<\/span><span class=\"hljs-params\">(<span class=\"hljs-built_in\">std<\/span>::is_same_v&lt;T, <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span>&gt;)<\/span> <\/span>{\r\n    <span class=\"hljs-keyword\">return<\/span> t;\r\n  } <span class=\"hljs-keyword\">else<\/span> {\r\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-built_in\">std<\/span>::to_string(t);\r\n  }\r\n}\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span>\r\n<\/span>{\r\n  <span class=\"hljs-keyword\">auto<\/span> x = stringify(<span class=\"hljs-number\">2<\/span>);\r\n  <span class=\"hljs-keyword\">auto<\/span> y = stringify(<span class=\"hljs-string\">\"hello\"<\/span>);\r\n}\r\n<\/code><\/pre>\n<p>It will not compile. The reason is, there is also no <code>to_string<\/code> for a char-array. We can fix this by providing an additional <code>if<\/code> for this <a href=\"https:\/\/cppinsights.io\/lnk?code=I2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPHR5cGVfdHJhaXRzPgoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnN0ZDo6c3RyaW5nIHN0cmluZ2lmeShUJiYgdCkKewogIGlmIGNvbnN0ZXhwcihzdGQ6OmlzX3NhbWVfdjxULCBzdGQ6OnN0cmluZz4pIHsKICAgIHJldHVybiB0OwogIH0gZWxzZSBpZiBjb25zdGV4cHIoc3RkOjppc19hcnJheV92PCBzdGQ6OnJlbW92ZV9yZWZlcmVuY2VfdDxUPiA+KSB7CiAgICByZXR1cm4gc3RkOjpzdHJpbmd7dH07CiAgfSBlbHNlIHsKICAgIHJldHVybiBzdGQ6OnRvX3N0cmluZyh0KTsKICB9Cn0KCmludCBtYWluKCkKewogIGF1dG8geCA9IHN0cmluZ2lmeSgyKTsKICBhdXRvIHkgPSBzdHJpbmdpZnkoImhlbGxvIik7Cn0=&amp;std=cpp17&amp;rev=1.0\">case<\/a>:<\/p>\n<pre><code class=\"language-C++\"><span class=\"hljs-preprocessor\">#<span class=\"hljs-keyword\">include<\/span> <span class=\"hljs-string\">&lt;string&gt;<\/span><\/span>\r\n<span class=\"hljs-preprocessor\">#<span class=\"hljs-keyword\">include<\/span> <span class=\"hljs-string\">&lt;type_traits&gt;<\/span><\/span>\r\n\r\n<span class=\"hljs-keyword\">template<\/span> &lt;<span class=\"hljs-keyword\">typename<\/span> T&gt;\r\n<span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-function\"><span class=\"hljs-built_in\">string<\/span> <span class=\"hljs-title\">stringify<\/span><span class=\"hljs-params\">(T&amp;&amp; t)<\/span>\r\n<\/span>{\r\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-title\">constexpr<\/span><span class=\"hljs-params\">(<span class=\"hljs-built_in\">std<\/span>::is_same_v&lt;T, <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span>&gt;)<\/span> <\/span>{\r\n    <span class=\"hljs-keyword\">return<\/span> t;\r\n  } <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-title\">constexpr<\/span><span class=\"hljs-params\">(<span class=\"hljs-built_in\">std<\/span>::is_array_v&lt; <span class=\"hljs-built_in\">std<\/span>::remove_reference_t&lt;T&gt; &gt;)<\/span> <\/span>{\r\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">string<\/span>{t};\r\n  } <span class=\"hljs-keyword\">else<\/span> {\r\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-built_in\">std<\/span>::to_string(t);\r\n  }\r\n}\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span>\r\n<\/span>{\r\n  <span class=\"hljs-keyword\">auto<\/span> x = stringify(<span class=\"hljs-number\">2<\/span>);\r\n  <span class=\"hljs-keyword\">auto<\/span> y = stringify(<span class=\"hljs-string\">\"hello\"<\/span>);\r\n}\r\n<\/code><\/pre>\n<p>Now it compiles. What C++ Insights shows you are the template instantiations for the two types. But there is more. It also shows which <code>if<\/code>-branch is used in that instantiation. If you look closely you can spot something else. C++ Insights shows you also that there is no <code>else if<\/code> in C++. There is just an <code>if<\/code> and a <code>else<\/code>. Why is this important? Because we need to apply the <code>constexpr<\/code> to all <code>if<\/code>-branches. Otherwise, we end up with a run-time if in a <code>constexpr if<\/code> else-branch.<\/p>\n<p>I\u2019d like to thank Rainer for the opportunity to share information about C++ Insights on his popular blog!<\/p>\n<p>Have fun with C++ Insights. You can support the project by becoming a <a href=\"https:\/\/www.patreon.com\/cppinsights\">Patreon<\/a> or<br \/>of course with code <a href=\"https:\/\/github.com\/andreasfertig\/cppinsights\">contributions<\/a>.<\/p>\n<p>Stay tuned for more insights about C++ Insights. The next post is about Variadic Templates.<\/p>\n<p><strong>Andreas<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today&#8217;s post from Andreas is about template instantiation. C++ Insights helps you a lot to get a deeper insight into this automatic process.<\/p>\n","protected":false},"author":21,"featured_media":5656,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[374],"tags":[],"class_list":["post-5657","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cppinsight"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5657","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=5657"}],"version-history":[{"count":0,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5657\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5656"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5657"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5657"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5657"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}