{"id":5218,"date":"2017-03-11T09:06:31","date_gmt":"2017-03-11T09:06:31","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/placeholders-the-second\/"},"modified":"2023-06-26T12:19:35","modified_gmt":"2023-06-26T12:19:35","slug":"placeholders-the-second","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/placeholders-the-second\/","title":{"rendered":"Placeholders &#8211; The Second"},"content":{"rendered":"<p>The unification of templates, concepts, and placeholders goes on. This time, I will look closely at constrained (concepts) and unconstrained <span style=\"font-family: courier new,courier;\">(auto)<\/span> placeholders in the context of templates.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p>First, a short reminder for you (and me). I stated in my last post <a href=\"https:\/\/www.modernescpp.com\/index.php\/concepts-placeholders\">Concepts -Placeholders<\/a>:&nbsp;You can use constrained placeholders (concepts) in each situation, whereas you can use unconstrained placeholders <span style=\"font-family: courier new,courier;\">(auto).<\/span> I used in the last post the concept <span style=\"font-family: courier new,courier;\">Integral<\/span> in the algorithm <span style=\"font-family: courier new,courier;\">gcd<\/span> to make it more type-safe. Let&#8217;s continue.<span style=\"font-family: courier new,courier;\"><br \/><\/span><\/p>\n<h2>Syntactic sugar and more<\/h2>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38\r\n39\r\n40\r\n41\r\n42\r\n43\r\n44\r\n45\r\n46\r\n47\r\n48\r\n49\r\n50\r\n51\r\n52\r\n53<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ conceptsIntegralVariations.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;type_traits&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">template<\/span>&lt;<span style=\"color: #0000ff;\">typename<\/span> T&gt;\r\nconcept <span style=\"color: #2b91af;\">bool<\/span> Integral(){\r\n  <span style=\"color: #0000ff;\">return<\/span> std::is_integral&lt;T&gt;::value;\r\n}\r\n\r\n<span style=\"color: #0000ff;\">template<\/span>&lt;<span style=\"color: #0000ff;\">typename<\/span> T&gt;\r\nrequires Integral&lt;T&gt;()\r\nT gcd(T a, T b){\r\n  <span style=\"color: #0000ff;\">if<\/span>( b == 0 ){ <span style=\"color: #0000ff;\">return<\/span> a; }\r\n  <span style=\"color: #0000ff;\">else<\/span>{\r\n    <span style=\"color: #0000ff;\">return<\/span> gcd(b, a % b);\r\n  }\r\n}\r\n\r\n<span style=\"color: #0000ff;\">template<\/span>&lt;Integral T&gt;\r\nT gcd1(T a, T b){\r\n  <span style=\"color: #0000ff;\">if<\/span>( b == 0 ){ <span style=\"color: #0000ff;\">return<\/span> a; }\r\n  <span style=\"color: #0000ff;\">else<\/span>{\r\n    <span style=\"color: #0000ff;\">return<\/span> gcd(b, a % b);\r\n  }\r\n}\r\n\r\nIntegral gcd2(Integral a, Integral b){\r\n  <span style=\"color: #0000ff;\">if<\/span>( b == 0 ){ <span style=\"color: #0000ff;\">return<\/span> a; }\r\n  <span style=\"color: #0000ff;\">else<\/span>{\r\n    <span style=\"color: #0000ff;\">return<\/span> gcd(b, a % b);\r\n  }\r\n}\r\n\r\n<span style=\"color: #0000ff;\">auto<\/span> gcd3(<span style=\"color: #0000ff;\">auto<\/span> a, <span style=\"color: #0000ff;\">auto<\/span> b){\r\n  <span style=\"color: #0000ff;\">if<\/span>( b == 0 ){ <span style=\"color: #0000ff;\">return<\/span> a; }\r\n  <span style=\"color: #0000ff;\">else<\/span>{\r\n    <span style=\"color: #0000ff;\">return<\/span> gcd(b, a % b);\r\n  }\r\n}\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n\r\n  std::cout &lt;&lt; std::endl;\r\n\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"gcd(100, 10)= \"<\/span>  &lt;&lt;  gcd(100, 10)  &lt;&lt; std::endl;\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"gcd1(100, 10)= \"<\/span> &lt;&lt;  gcd1(100, 10)  &lt;&lt; std::endl;\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"gcd2(100, 10)= \"<\/span> &lt;&lt;  gcd2(100, 10)  &lt;&lt; std::endl;\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"gcd3(100, 10)= \"<\/span> &lt;&lt;  gcd3(100, 10)  &lt;&lt; std::endl;\r\n\r\n  std::cout &lt;&lt; std::endl;\r\n\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Don&#8217;t get me wrong. I&#8217;m a big fan of<a href=\"https:\/\/en.wikipedia.org\/wiki\/Syntactic_sugar\"> syntactic sugar<\/a>. Syntactic sugar makes a feature easier to use, and you can write more expressive and less error-prone code. Isn&#8217;t C++ only syntactic sugar for C or assembler?<\/p>\n<p>I define in lines 7 -9 the concept <span style=\"font-family: courier new,courier;\">Integral<\/span> that I use in the algorithm <span style=\"font-family: courier new,courier;\">gcd<\/span> (lines 11 &#8211; 18). Now,&nbsp; I make the syntax sweeter. Instead of specifying the concept in the required clause (line 12), I can use it instead of the keyword <span style=\"font-family: courier new,courier;\">typename<\/span> or <span style=\"font-family: courier new,courier;\">class<\/span> for the type parameter (line 20). It gets even sweeter\u2014the concept <span style=\"font-family: courier new,courier;\">Integral<\/span> is used in line 28 as a function parameter. Of course, <span style=\"font-family: courier new,courier;\">gcd2<\/span> becomes, by using the concept, a function template. Now the unification kicks in. I will get an unconstrained function template if I replace a constrained placeholder (Integral) in line 28 with the unconstrained placeholders (auto) in line 35<em>.<\/em> Sorry about my newly coined term, unconstrained function template. I mean, <span style=\"font-family: courier new,courier;\">gcd3<\/span> is a template that can accept values of arbitrary type.<\/p>\n<p>To wrap up my sentences, here is the output of the program.<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5214\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/conceptsIntegralVariations.png\" alt=\"conceptsIntegralVariations\" style=\"margin: 15px;\" width=\"488\" height=\"188\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/conceptsIntegralVariations.png 488w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/conceptsIntegralVariations-300x116.png 300w\" sizes=\"auto, (max-width: 488px) 100vw, 488px\" \/><\/p>\n<p>I called this section &#8220;Syntactic sugar and more&#8221;. But why more? You will see.<\/p>\n<\/p>\n<h3>Syntactic sugar and<strong> more<\/strong><\/h3>\n<p>The function template <span style=\"font-family: courier new,courier;\">gcd2<\/span> is more potent than the function template <span style=\"font-family: courier new,courier;\">gcd<\/span> or <span style=\"font-family: courier new,courier;\">gcd1.<\/span> <span style=\"font-family: courier new,courier;\">gcd2<\/span> has two type parameters that have not to be the same. Both have to respect the concept of Integral. The same observations hold for the function template <span style=\"font-family: courier new,courier;\">gcd3.<\/span> <span style=\"font-family: courier new,courier;\">a<\/span> and <span style=\"font-family: courier new,courier;\">b<\/span> have not to be of the same type. Using the function template <span style=\"font-family: courier new,courier;\">twoTypes<\/span> in line 39 makes my point clear.<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38\r\n39\r\n40\r\n41\r\n42\r\n43<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ placeholders.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;typeinfo&gt;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">template<\/span>&lt;<span style=\"color: #0000ff;\">typename<\/span> T&gt;\r\nconcept <span style=\"color: #2b91af;\">bool<\/span> Integral(){\r\n  <span style=\"color: #0000ff;\">return<\/span> std::is_integral&lt;T&gt;::value;\r\n}\r\n\r\n<span style=\"color: #2b91af;\">void<\/span> overload(<span style=\"color: #0000ff;\">auto<\/span> t){\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"auto : \"<\/span> &lt;&lt; t &lt;&lt; std::endl;\r\n}\r\n\r\n<span style=\"color: #2b91af;\">void<\/span> overload(Integral t){\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"Integral : \"<\/span> &lt;&lt; t &lt;&lt; std::endl;\r\n}\r\n\r\n<span style=\"color: #2b91af;\">void<\/span> overload(<span style=\"color: #2b91af;\">long<\/span> t){\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"long : \"<\/span> &lt;&lt; t &lt;&lt; std::endl;\r\n}\r\n  \r\n<span style=\"color: #2b91af;\">void<\/span> twoTypes(<span style=\"color: #0000ff;\">auto<\/span> a, <span style=\"color: #0000ff;\">auto<\/span> b){\r\n  std::cout &lt;&lt; <span style=\"color: #0000ff;\">typeid<\/span>(a).name() &lt;&lt; std::endl;\r\n  std::cout &lt;&lt; <span style=\"color: #0000ff;\">typeid<\/span>(b).name() &lt;&lt; std::endl;\r\n}\r\n\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n  \r\n  std::cout &lt;&lt; std::endl;\r\n  \r\n  overload(3.14);\r\n  overload(2010);\r\n  overload(2020l);\r\n  \r\n  std::cout &lt;&lt; std::endl;\r\n  \r\n  twoTypes(2010, 3.14); \r\n  \r\n  std::cout &lt;&lt; std::endl;\r\n\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>&nbsp;With a little bit of <strong>R<\/strong>un <strong>T<\/strong>ime <strong>T<\/strong>ype <strong>I<\/strong>nfomation (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Run-time_type_information\">RTTI)<\/a> in line 24 and 25, I get a string representation of the types. As expected, the types are <span style=\"font-family: courier new,courier;\">int<\/span> and <span style=\"font-family: courier new,courier;\">double. <\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5215\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/placeholders.png\" alt=\"placeholders\" style=\"margin: 15px;\" width=\"379\" height=\"219\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/placeholders.png 379w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/placeholders-300x173.png 300w\" sizes=\"auto, (max-width: 379px) 100vw, 379px\" \/><\/p>\n<p>But the short example shows more. The interplay between the unconstrained function template (line 11), the constrained function template (line 15), and the function (line 19) is very smooth. That is precisely the behavior, I expected.<\/p>\n<p>If you hate the classical way of declaring templates, there is a new way.<\/p>\n<h2>Template introduction<\/h2>\n<p>Instead of declaring your constrained template by using <span style=\"font-family: courier new,courier;\">template&lt;Integral T&gt;<\/span>, you can now just right <span style=\"font-family: courier new,courier;\">Integral{T}<\/span>. Once more, I wrote constrained templates. So, you have to use concepts.&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38\r\n39\r\n40\r\n41\r\n42\r\n43\r\n44\r\n45\r\n46\r\n47\r\n48\r\n49<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ templateIntroduction.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;type_traits&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">template<\/span>&lt;<span style=\"color: #0000ff;\">typename<\/span> T&gt;\r\nconcept <span style=\"color: #2b91af;\">bool<\/span> Integral(){\r\n  <span style=\"color: #0000ff;\">return<\/span> std::is_integral&lt;T&gt;::value;\r\n}\r\n\r\nIntegral{T}\r\nIntegral gcd(T a, T b){\r\n  <span style=\"color: #0000ff;\">if<\/span>( b == 0 ){ <span style=\"color: #0000ff;\">return<\/span> a; }\r\n  <span style=\"color: #0000ff;\">else<\/span>{\r\n    <span style=\"color: #0000ff;\">return<\/span> gcd(b, a % b);\r\n  }\r\n}\r\n\r\nIntegral{T} \r\n<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">ConstrainedClass<\/span>{};\r\n\r\n<span style=\"color: #008000;\">\/*<\/span>\r\n\r\n<span style=\"color: #008000;\">auto{T}<\/span>\r\n<span style=\"color: #008000;\">auto gcd(T a, T b){<\/span>\r\n<span style=\"color: #008000;\">  if( b == 0 ){ return a; }<\/span>\r\n<span style=\"color: #008000;\">  else{<\/span>\r\n<span style=\"color: #008000;\">    return gcd(b, a % b);<\/span>\r\n<span style=\"color: #008000;\">  }<\/span>\r\n<span style=\"color: #008000;\">}<\/span>\r\n\r\n<span style=\"color: #008000;\">auto{T} <\/span>\r\n<span style=\"color: #008000;\">class ConstrainedClass{};<\/span>\r\n\r\n<span style=\"color: #008000;\">*\/<\/span>\r\n\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n  \r\n  std::cout &lt;&lt; std::endl;\r\n  \r\n  <span style=\"color: #0000ff;\">auto<\/span> res= gcd(100, 10); \r\n\r\n  ConstrainedClass&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; constrainedClass;\r\n  ConstrainedClass&lt;<span style=\"color: #2b91af;\">double<\/span>&gt; constrainedClass1;\r\n  \r\n  std::cout &lt;&lt; std::endl;\r\n\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>I used the new syntax for the function template <span style=\"font-family: courier new,courier;\">gcd<\/span> in line 11 and the class-template <span style=\"font-family: comic sans ms,sans-serif;\">ConstrainedClass<\/span> in line <span style=\"font-family: courier new,courier;\">19<\/span>. The concept will kick in if I try to instantiate <span style=\"font-family: courier new,courier;\">ConstraintedClass<\/span> for <span style=\"font-family: courier new,courier;\">double<\/span> (line 45).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5216\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/templateIntroductionError.png\" alt=\"templateIntroductionError\" width=\"864\" height=\"214\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/templateIntroductionError.png 864w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/templateIntroductionError-300x74.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/templateIntroductionError-768x190.png 768w\" sizes=\"auto, (max-width: 864px) 100vw, 864px\" \/><\/p>\n<p>I don&#8217;t like that I can not replace <span style=\"font-family: courier new,courier;\">Integral<\/span> with <span style=\"font-family: courier new,courier;\">auto<\/span>, such as in lines 24 to 33. In my posts, I have used a constrained placeholder instead of an unconstrained placeholder and the other way around. That is a simple principle.<\/p>\n<p>Of course, I can overcome this restriction by using a concept that constantly evaluates to <span style=\"font-family: courier new,courier;\">true.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38\r\n39\r\n40\r\n41\r\n42\r\n43\r\n44\r\n45<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ templateIntroductionGeneric.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;string&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;typeinfo&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;utility&gt;<\/span>\r\n\r\n\r\n<span style=\"color: #0000ff;\">template<\/span>&lt;<span style=\"color: #0000ff;\">typename<\/span> T&gt;\r\nconcept <span style=\"color: #2b91af;\">bool<\/span> Generic(){\r\n  <span style=\"color: #0000ff;\">return<\/span> true;\r\n}\r\n\r\nGeneric{T}\r\nGeneric gcd(T a, T b){\r\n  <span style=\"color: #0000ff;\">if<\/span>( b == 0 ){ <span style=\"color: #0000ff;\">return<\/span> a; }\r\n  <span style=\"color: #0000ff;\">else<\/span>{\r\n    <span style=\"color: #0000ff;\">return<\/span> gcd(b, a % b);\r\n  }\r\n}\r\n\r\nGeneric{T} \r\n<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">ConstrainedClass<\/span>{\r\npublic:\r\n  ConstrainedClass(){\r\n    std::cout &lt;&lt; <span style=\"color: #0000ff;\">typeid<\/span>(decltype(std::declval&lt;T&gt;())).name() &lt;&lt; std::endl;\r\n  }\r\n};\r\n\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n  \r\n  std::cout &lt;&lt; std::endl;\r\n  \r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"gcd(100, 10): \"<\/span> &lt;&lt; gcd(100, 10) &lt;&lt; std::endl;\r\n  \r\n  std::cout &lt;&lt; std::endl;\r\n \r\n  ConstrainedClass&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; genericClassInt;\r\n  ConstrainedClass&lt;std::string&gt; genericClassString;\r\n  ConstrainedClass&lt;<span style=\"color: #2b91af;\">double<\/span>&gt; genericClassDouble;\r\n  \r\n  std::cout &lt;&lt; std::endl;\r\n\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p><span style=\"font-family: courier new,courier;\">Generic<\/span> (lines 9 &#8211; 12) is my concept that returns <span style=\"font-family: courier new,courier;\">true<\/span> for all types. Now, I can unify the syntax and define an unconstrained function template (lines 14 &#8211; 20) and an unconstrained class template (lines 22 &#8211; 28). Sorry for the expression<span style=\"font-family: courier new,courier;\">&nbsp;typeid(decltype(std::declval&lt;T&gt;())).name()<\/span> in line 26 that works even for a type T without a default constructor. This expression returns the string representation of the type parameter T. Here is the program&#8217;s output.&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5217\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/templateIntroductionGeneric.png\" alt=\"templateIntroductionGeneric\" style=\"margin: 15px;\" width=\"514\" height=\"178\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/templateIntroductionGeneric.png 514w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/templateIntroductionGeneric-300x104.png 300w\" sizes=\"auto, (max-width: 514px) 100vw, 514px\" \/><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>I always use the same concept <span style=\"font-family: courier new,courier;\">Integral<\/span>, in my examples. Bored? That will change. I will write in my <a href=\"https:\/\/www.modernescpp.com\/index.php\/defintion-of-concepts\">next post<\/a> about defining concepts.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The unification of templates, concepts, and placeholders goes on. This time, I will look closely at constrained (concepts) and unconstrained (auto) placeholders in the context of templates.<\/p>\n","protected":false},"author":21,"featured_media":5214,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[365],"tags":[415,482],"class_list":["post-5218","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-functional","tag-concepts","tag-outdated"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5218","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=5218"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5218\/revisions"}],"predecessor-version":[{"id":6878,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5218\/revisions\/6878"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5214"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5218"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5218"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5218"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}