{"id":5948,"date":"2020-07-24T08:27:34","date_gmt":"2020-07-24T08:27:34","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/template-improvements-with-c-20\/"},"modified":"2020-07-24T08:27:34","modified_gmt":"2020-07-24T08:27:34","slug":"template-improvements-with-c-20","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/template-improvements-with-c-20\/","title":{"rendered":"Various Template Improvements with C++20"},"content":{"rendered":"<p>Admittedly, I present in this post a few minor improvements to templates and C++20 in general. Although these improvements may not seem so impressive to you, they make C++20 more consistent and less error-prone when you program generic.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5945\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/TimelineCpp20CoreLanguage.png\" alt=\"TimelineCpp20CoreLanguage\" width=\"650\" height=\"277\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/TimelineCpp20CoreLanguage.png 950w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/TimelineCpp20CoreLanguage-300x128.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/TimelineCpp20CoreLanguage-768x327.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>Today&#8217;s post is about conditionally explicit constructors and new non-type template parameters.<\/p>\n<h2>Conditionally Explicit Constructors<\/h2>\n<p>Sometimes, you want to have a class that should has constructors accepting various types. For example, you have a class <span style=\"font-family: courier new, courier;\">VariantWrapper<\/span> which holds a <span style=\"font-family: 'courier new', courier;\">std::variant<\/span> accepting different types.<\/p>\n<p><!-- HTML generated using hilite.me --><\/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;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">VariantWrapper<\/span> {\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>variant<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">bool<\/span>, <span style=\"color: #007788; font-weight: bold;\">char<\/span>, <span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #007788; font-weight: bold;\">double<\/span>, <span style=\"color: #007788; font-weight: bold;\">float<\/span>, std<span style=\"color: #555555;\">::<\/span>string<span style=\"color: #555555;\">&gt;<\/span> myVariant;\r\n\r\n};\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>To initialize the myVariant with <span style=\"font-family: courier new, courier;\">bool, char, int, double, float,<\/span>&nbsp;or&nbsp;<span style=\"font-family: courier new, courier;\">std::string, <\/span>the class <span style=\"font-family: courier new, courier;\">VariantWrapper<\/span> needs constructors for each listed type. Laziness is a virtue &#8211; at least for programmers &#8211; , therefore, you decide to make the constructor generic.&nbsp;<\/p>\n<p><span style=\"font-family: courier new, courier;\"><\/span>The class<span style=\"font-family: courier new, courier;\"> Implicit<\/span>&nbsp;exemplifies a generic constructor.<\/p>\n<p><span style=\"font-family: courier new, courier;\"><\/span><\/p>\n<p><!-- HTML generated using hilite.me --><\/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;\">\/\/ explicitBool.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;string&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;type_traits&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> Implicit {\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 style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span><\/span>\r\n    Implicit(T t) {\r\n        std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> t <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    }\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> Explicit {\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;\">explicit<\/span> Explicit(T t) {    <span style=\"color: #555555;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span><\/span>\r\n        std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> t <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\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>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n    Implicit imp1 <span style=\"color: #555555;\">=<\/span> <span style=\"color: #cc3300;\">\"implicit\"<\/span>;\r\n    Implicit imp2(<span style=\"color: #cc3300;\">\"explicit\"<\/span>);\r\n    Implicit imp3 <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">1998<\/span>;\r\n    Implicit imp4(<span style=\"color: #ff6600;\">1998<\/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    <span style=\"color: #0099ff; font-style: italic;\">\/\/ Explicit exp1 = \"implicit\";  \/\/ (3)<\/span>\r\n    Explicit exp2{<span style=\"color: #cc3300;\">\"explicit\"<\/span>};      <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ Explicit exp3 = 2011;        \/\/ (3)<\/span>\r\n    Explicit exp4{<span style=\"color: #ff6600;\">2011<\/span>};            <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/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} \r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Now, you have an issue. A generic constructor (1) is a catch-all constructor because you can invoke them with any type. The constructor is way too greedy.&nbsp; By putting an <span style=\"font-family: courier new, courier;\">explicit<\/span> in front of the constructor (2). the constructor becomes explicit. This means that implicit conversions (3) are not valid anymore. Only explicit calls (4) are valid.<\/p>\n<p>Thanks to Clang 10, here is the output of the program:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5946\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/explicitBool.png\" alt=\"explicitBool\" width=\"300\" height=\"236\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/explicitBool.png 1118w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/explicitBool-300x236.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/explicitBool-1024x807.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/explicitBool-768x605.png 768w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>This is not the and of the story. Maybe, you have a type <span style=\"font-family: courier new, courier;\">MyBool<\/span> that should only support the implicit conversion from <span style=\"font-family: courier new, courier;\">bool, <\/span>but no other implicit conversion<span style=\"font-family: courier new, courier;\">.<\/span> In this case, explicit can be used conditionally.<\/p>\n<p><!-- HTML generated using hilite.me --><\/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;\">\/\/ myBool.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;type_traits&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;typeinfo&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> MyBool {\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;\">explicit<\/span>(<span style=\"color: #555555;\">!<\/span>std<span style=\"color: #555555;\">::<\/span>is_same<span style=\"color: #555555;\">&lt;<\/span>T, <span style=\"color: #007788; font-weight: bold;\">bool<\/span><span style=\"color: #555555;\">&gt;::<\/span>value) MyBool(T t) {  <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: #006699; font-weight: bold;\">typeid<\/span>(t).name() <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    }\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">needBool<\/span>(MyBool b){ }                                 <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\r\n\r\n    MyBool myBool1(<span style=\"color: #336666;\">true<\/span>);                              \r\n    MyBool myBool2 <span style=\"color: #555555;\">=<\/span> <span style=\"color: #336666;\">false<\/span>;                                <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n    \r\n    needBool(myBool1);\r\n    needBool(<span style=\"color: #336666;\">true<\/span>);                                        <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ needBool(5);<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ needBool(\"true\");<\/span>\r\n    \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The <span style=\"font-family: courier new, courier;\">explicit(!std::is_same&lt;T,&nbsp; bool&gt;::value)<\/span> expression guarantees that <span style=\"font-family: courier new, courier;\">MyBool<\/span> can only be implicitly created from a <span style=\"font-family: courier new, courier;\">bool&nbsp;<\/span>value. The function <span style=\"font-family: courier new, courier;\">std::is_same is<\/span> a compile-time predicate from the <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/header\/type_traits\">type_traits library<\/a>. Compile-time predicate means <span style=\"font-family: courier new, courier;\">std::is_same<\/span> is evaluated at compile-time and returns a boolean. Consequently, the implicit conversion from <span style=\"font-family: courier new, courier;\">bool<\/span> in (3) and (4) is possible, but not the commented-out conversions from <span style=\"font-family: courier new, courier;\">int<\/span> and a C-string.<\/p>\n<p>You are right when you argue that a conditionally explicit constructor would be possible with <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/sfinae\">SFINAE<\/a>. But honestly, I wouldn&#8217;t say I like the corresponding SFINAE using a constructor, because it would take me a few lines to explain it. Additionally, I only get it right after the third try.<\/p>\n<p><!-- HTML generated using hilite.me --><\/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, std<span style=\"color: #555555;\">::<\/span><span style=\"color: #007788; font-weight: bold;\">enable_if_t<\/span><span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>is_same_v<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span><span style=\"color: #007788; font-weight: bold;\">decay_t<\/span><span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span>, <span style=\"color: #007788; font-weight: bold;\">bool<\/span><span style=\"color: #555555;\">&gt;<\/span>, <span style=\"color: #007788; font-weight: bold;\">bool<\/span><span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #555555;\">=<\/span> <span style=\"color: #336666;\">true<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\nMyBool(T<span style=\"color: #555555;\">&amp;&amp;<\/span> t) {\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #006699; font-weight: bold;\">typeid<\/span>(t).name() <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>I should add a few explaining words. <span style=\"font-family: courier new, courier;\">std::enable_if <\/span>is a convenient way to use SFINAE. SFINAE stands for <strong>S<\/strong>ubstitution<strong> F<\/strong>ailure <strong>I<\/strong>s <strong>N<\/strong>ot <strong>A<\/strong>n <strong>E<\/strong>rror and applies during overload resolution of a function template. When substituting the template parameter fails, the specialization is discarded from the overload set but causes no compiler error. This exactly happens in this concrete case. The specialization is discarded if<span style=\"font-family: courier new, courier;\"> std::is_same_v&lt;std::decay_t&lt;T&gt;, bool&gt;<\/span> evaluates to false. <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/types\/decay\"><span style=\"font-family: courier new, courier;\">std::decay&lt;T&gt;<\/span><\/a> applies conversions to <span style=\"font-family: courier new, courier;\">T<\/span>, such as removing <span style=\"font-family: courier new, courier;\">const<\/span>, <span style=\"font-family: courier new, courier;\">volatile<\/span> or a reference from <span style=\"font-family: courier new, courier;\">T. std::decay_t&lt;T&gt;<\/span> is a convenient syntax for <span style=\"font-family: courier new, courier;\">std::decay&lt;T&gt;::type. <\/span>The same holds for <span style=\"font-family: courier new, courier;\">std::is_same_v&lt;T, bool&gt;<\/span>, which is short for <span style=\"font-family: courier new, courier;\">std::is_same&lt;T, bool&gt;::value. <\/span><\/p>\n<p><strong>As my German reader pre alpha pointed out: the constructor using SFINAE is way too greedy. It disables all non-bool constructors.<\/strong><\/p>\n<p>Beside my longish explanation, an additional argument speaks against SFINAE and for a conditionally explicit constructor: performance. Simon Brand pointed out in his post &#8220;<a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/c20s-conditionally-explicit-constructors\/\">C++20&#8217;s Conditionally Explicit Constructors<\/a>&#8220;, that <span style=\"font-family: 'courier new', courier;\">explicit(bool)<\/span> made the template instantiation for Visual Studio 2019 about 15% faster compared to SFINAE.<\/p>\n<p>With C++20, additional non-type template parameters are supported.<\/p>\n<\/p>\n<h2>New non-type Template Parameter<\/h2>\n<p>With C++20, floating points and classes with <span style=\"font-family: courier new, courier;\">constexpr<\/span> constructors are supported as non-types.<\/p>\n<p>C++ supports non-types as template parameters. Essentially non-types could be<\/p>\n<ul>\n<li>integers and enumerators<\/li>\n<li>pointer&nbsp; or references to objects, functions, and to attributes of a class<\/li>\n<li><span style=\"font-family: courier new, courier;\">std::nullptr_t<\/span><\/li>\n<\/ul>\n<p>When I ask the students in my class if they ever used a non-type as a template parameter, they say: No! Of course, I answer my tricky question and show an often-used example for non-type template parameters:<\/p>\n<p><!-- HTML generated using hilite.me --><\/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%;\">std<span style=\"color: #555555;\">::<\/span>array<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #ff6600;\">5<\/span><span style=\"color: #555555;\">&gt;<\/span> myVec;\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>5 is a non-type and is used as a template argument. We are just used to it. Since the first C++-standard C++98, there is a discussion in the C++ community to support floating points as a template parameter. Now, we C++20, we have it:<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/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;\">\/\/ nonTypeTemplateParameter.cpp<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> ClassType {\r\n    constexpr ClassType(<span style=\"color: #007788; font-weight: bold;\">int<\/span>) {}  <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>ClassType cl<span style=\"color: #555555;\">&gt;          <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span><\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> getClassType() {\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> cl;\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;\">double<\/span> d<span style=\"color: #555555;\">&gt;              <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span><\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> getDouble() {\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> d;\r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> main() {\r\n\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> c1 <span style=\"color: #555555;\">=<\/span> getClassType<span style=\"color: #555555;\">&lt;<\/span>ClassType(<span style=\"color: #ff6600;\">2020<\/span>)<span style=\"color: #555555;\">&gt;<\/span>();\r\n\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> d1 <span style=\"color: #555555;\">=<\/span> getDouble<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #ff6600;\">5.5<\/span><span style=\"color: #555555;\">&gt;<\/span>();  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span><span style=\"color: #555555;\"><\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> d2 <span style=\"color: #555555;\">=<\/span> getDouble<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #ff6600;\">6.5<\/span><span style=\"color: #555555;\">&gt;<\/span>();  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span><span style=\"color: #555555;\"><\/span>\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>ClassType has a constexpr constructor (1) and can be used as a template argument (2). The same holds for the function template&nbsp;<span style=\"font-family: courier new, courier;\">getDouble<\/span> (3), which accepts only doubles. I want to emphasize that each call of the function template&nbsp;<span style=\"font-family: courier new, courier;\">getDouble<\/span> (4) with a new argument triggers the instantiation of a new function <span style=\"font-family: courier new, courier;\">getDouble<\/span>.&nbsp; This means that two instantiations for the doubles 5.5 and 6.5 are created.<\/p>\n<p>If Clang would already supports this feature, I could show you with C++ Insights that each instantiation for 5.5 and 6.5 creates a fully specialized function template. At least, thanks to GCC, I can show you the relevant assembler instructions with the <a href=\"https:\/\/godbolt.org\/\">Compiler Explorer.<\/a><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5947\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/nonTypeTemplateParameter.png\" alt=\"nonTypeTemplateParameter\" width=\"450\" height=\"287\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/nonTypeTemplateParameter.png 1203w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/nonTypeTemplateParameter-300x192.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/nonTypeTemplateParameter-1024x654.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/nonTypeTemplateParameter-768x490.png 768w\" sizes=\"auto, (max-width: 450px) 100vw, 450px\" \/><\/p>\n<p>The screenshot shows that the compiler created for each template argument a function.<\/p>\n<h3>What&#8217;s next?<\/h3>\n<p>As templates, lambdas are also improved in various ways in C++20. My <a href=\"https:\/\/www.modernescpp.com\/index.php\/more-powerful-lambdas-with-c-20\">next post <\/a>is about these various improvements.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Admittedly, I present in this post a few minor improvements to templates and C++20 in general. Although these improvements may not seem so impressive to you, they make C++20 more consistent and less error-prone when you program generic.<\/p>\n","protected":false},"author":21,"featured_media":5945,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[375],"tags":[],"class_list":["post-5948","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c-20"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5948","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=5948"}],"version-history":[{"count":0,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5948\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5945"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5948"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5948"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5948"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}