{"id":5213,"date":"2017-03-05T16:54:32","date_gmt":"2017-03-05T16:54:32","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/concepts-placeholders\/"},"modified":"2023-06-26T12:20:07","modified_gmt":"2023-06-26T12:20:07","slug":"concepts-placeholders","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/concepts-placeholders\/","title":{"rendered":"Concepts &#8211; Placeholders"},"content":{"rendered":"<p>C++11 has auto unconstrained placeholders. You can use concepts in C++20 as constrained placeholders. What seems at first glimpse not so thrilling is for me the decisive quantum leap. C++ templates will become an easy to use C++ feature.<\/p>\n<p><!--more--><\/p>\n<p><em>Before I present the new syntax, I have to make a short remark. After my research to concepts and my experiments with unconstrained and constrained placeholders, I&#8217;m very biased. Therefore you can not expect a quite objective post. &nbsp;&nbsp;<\/em><\/p>\n<h2>An ever and ever-recurring question<\/h2>\n<p>I hear often in my C++ and Python seminars the question: When is a programming language easy? Of course, the answer can not be that a programming language is easy if you can solve difficult questions in an easy way. That is a contradiction.<\/p>\n<p>For me, a programming language is easy if you can reduce it to a few simple principles. I call such a principle a <b>red thread<\/b>. I hope you get the German proverb. The idea of these few simple principles is that you can deduce the features of the language from these principles. According to my definition, Python is a simple programming language. For example, if you get the idea of building slices on a sequence, you can apply this principle in many contexts.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5209\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/slice.png\" alt=\"slice\" width=\"560\" height=\"402\" style=\"margin: 15px;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/slice.png 560w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/slice-300x215.png 300w\" sizes=\"auto, (max-width: 560px) 100vw, 560px\" \/><\/p>\n<p>Therefore, the syntax will follow the same principle if I want to return each third element of a just-in-place created range <span style=\"font-family: courier new,courier;\">range(0,10,3),<\/span> a string,&nbsp; a list, or a tuple. The same principle will hold if I return the second element of a just-in-place created range <span style=\"font-family: courier new,courier;\">range(9,0,-2)<\/span>,&nbsp; a string, a list or a tuple in reverse order.<\/p>\n<p>According to my definition, C++98 is not a simple language. C++11 is something in between. For example, we have rules such as you can initialize all with curly braces (see<a href=\"https:\/\/www.modernescpp.com\/index.php\/initialization\"> { } &#8211; Initialization<\/a>). Of course, even C++14 has a lot of features where I miss a simple principle. One of my favourites is the generalised lambda function.<\/p>\n<div style=\"background: #ffffff none repeat scroll 0% 0%; overflow: auto; width: auto; border-width: 0.1em 0.1em 0.1em 0.8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0px; line-height: 125%;\">1\r\n2\r\n3\r\n4\r\n5\r\n6<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #0000ff;\">auto<\/span> genLambdaFunction= [](<span style=\"color: #0000ff;\">auto<\/span> a, <span style=\"color: #0000ff;\">auto<\/span> b) { <span style=\"color: #0000ff;\">return<\/span> a &lt; b; };\r\n\r\n<span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">typename<\/span> T, <span style=\"color: #0000ff;\">typename<\/span> T2&gt;\r\n<span style=\"color: #0000ff;\">auto<\/span> genFunction(T a, T2 b){\r\n  <span style=\"color: #0000ff;\">return<\/span> a &lt; b;\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>By using the placeholder <span style=\"font-family: courier;\">auto<\/span> for the parameter <span style=\"font-family: courier;\">a<\/span> and <span style=\"font-family: courier;\">b <\/span>the generalised lambda function becomes in a magic way a function template. (I know, <span style=\"font-family: Courier New,Courier,monospace;\">genLambdaFunction<\/span> is a function object that has an overloaded call operator which accepts two type parameters.). <span style=\"font-family: Courier New,Courier,monospace;\">genFunction<\/span> is also a function template but you can not just define it by using <span style=\"font-family: courier;\">auto<\/span>. Hence you have to use a lot more syntax (line 3 and 4). That is the syntax which is often too difficult for a lot of C++ programmer.&nbsp;<\/p>\n<p>Exactly that asymmetry will be removed with the placeholder syntax. Therefore, we have a new simple principle and C++ will become &#8211; according to my definition &#8211; a lot easier to use.<\/p>\n<\/p>\n<h2>Placeholders<\/h2>\n<p>We will get unconstrained and constrained placeholders. <span style=\"font-family: courier;\">auto<\/span> is an unconstrained placeholder because a&nbsp;<span style=\"font-family: Courier New,Courier,monospace;\">auto<\/span> defined variable can be of any type. A concept is a constrained placeholder because it can only be used to define a variable that satisfies the concept. I introduced concepts in the post <a href=\"https:\/\/www.modernescpp.com\/index.php\/concepts-lite\">Concepts<\/a> with the help of Haskell&#8217;s type classes. I got international praise and blame for my approach.<\/p>\n<p>Let me define and use a simple concept before I dig into the details.<\/p>\n<h3>A simple concept<\/h3>\n<p>Thanks to the concept <span style=\"font-family: courier new,courier;\">Integral<\/span>, the arguments of my gcd algorithm have to be integrals.<\/p>\n<div style=\"background: #ffffff none repeat scroll 0% 0%; overflow: auto; width: auto; border-width: 0.1em 0.1em 0.1em 0.8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0px; 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<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ conceptsIntegral.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: #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;\">\"gcd(100, 33)= \"<\/span> &lt;&lt; gcd(100, 33) &lt;&lt; std::endl;\r\n  <span style=\"color: #008000;\">\/\/ std::cout &lt;&lt; \"gcd(5.5, 4,5)= \" &lt;&lt; gcd(5.5, 4.5) &lt;&lt; std::endl;<\/span>\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 define in line 6 the concept&nbsp; <span style=\"font-family: courier new,courier;\">Integral.<\/span> The concept <span style=\"font-family: courier;\">Integral<\/span> will evaluate to true if the predicate <span style=\"font-family: courier new,courier;\">std::is_integral&lt;T&gt;::value returns true<\/span> for T. <span style=\"font-family: courier new,courier;\">std::is_integral&lt;T&gt;<\/span> is a function of the type-traits library. The functions of the type-traits library enable amongst other things that you can check types at compile time. You can read the details about the type-traits in the posts about the <a href=\"https:\/\/www.modernescpp.com\/index.php\/tag\/type-traits\">type-traits library<\/a>.&nbsp; In particular,&nbsp; I used the functions of the type-traits library to make the gcd algorithm more and more type-safe: <a href=\"https:\/\/www.modernescpp.com\/index.php\/more-and-more-save\">More and More Save<\/a>. I applied the concept in line 12. I will write in my next post how you can apply a concept in a simpler way. Therefore, the border between function templates and function successively distinguish.<\/p>\n<p>But now, back to my small example. Thanks to the relatively new GCC 6.3 and the compiler flag <span style=\"font-family: courier new,courier;\">-fconcepts<\/span>, I can compile and run the program.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5210\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/conceptsIntegral.png\" alt=\"conceptsIntegral\" style=\"margin: 15px;\" width=\"387\" height=\"158\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/conceptsIntegral.png 387w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/conceptsIntegral-300x122.png 300w\" sizes=\"auto, (max-width: 387px) 100vw, 387px\" \/><\/p>\n<p>What will happen if I use line 26? The concept kicks in.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5211\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/conceptsIntegralError.png\" alt=\"conceptsIntegralError\" width=\"700\" height=\"188\" style=\"margin: 15px;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/conceptsIntegralError.png 987w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/conceptsIntegralError-300x81.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/conceptsIntegralError-768x206.png 768w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/p>\n<p>Once more, back to the placeholders. To be specific, constrained and unconstrained placeholders.<\/p>\n<h3>Constrained and unconstrained placeholders<\/h3>\n<p>You can use constrained placeholders (concepts) in each situation where you can use unconstrained placeholders (<span style=\"font-family: courier new,courier;\">auto<\/span>). <strong>If this is not an intuitive rule?<\/strong><\/p>\n<div style=\"background: #ffffff none repeat scroll 0% 0%; overflow: auto; width: auto; border-width: 0.1em 0.1em 0.1em 0.8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0px; 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<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ conceptsPlaceholder.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;type_traits&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;vector&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 getIntegral(<span style=\"color: #0000ff;\">auto<\/span> val){\r\n  <span style=\"color: #0000ff;\">return<\/span> val;\r\n}\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n  \r\n  std::cout &lt;&lt; std::boolalpha &lt;&lt; std::endl;\r\n  \r\n  std::vector&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; myVec{1, 2, 3, 4, 5};\r\n  <span style=\"color: #0000ff;\">for<\/span> (Integral&amp; i: myVec) std::cout &lt;&lt; i &lt;&lt; <span style=\"color: #a31515;\">\" \"<\/span>;\r\n  std::cout &lt;&lt; std::endl;  \r\n\r\n  Integral b= true;\r\n  std::cout &lt;&lt; b &lt;&lt; std::endl;\r\n  \r\n  Integral integ= getIntegral(10);\r\n  std::cout &lt;&lt; integ &lt;&lt; std::endl;\r\n  \r\n  <span style=\"color: #0000ff;\">auto<\/span> integ1= getIntegral(10);\r\n  std::cout &lt;&lt; integ1 &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>For simplicity reasons, I reuse the concept <span style=\"font-family: courier;\">Integral<\/span> in line 7 &#8211; 10. Hence I iterate over integrals in the range-based for-loop in line 21 and my variable <span style=\"font-family: Courier New,Courier,monospace;\">b<\/span> in line 24 has to be integral. My usage of concepts goes on in line 27 and 30. I require in line 27 that the return type of <span style=\"font-family: courier new,courier;\">getIntegral(10)<\/span> has to fulfil the concept <span style=\"font-family: courier new,courier;\">Integral<\/span>.&nbsp; I&#8217;m not so strict in line 30. Here I&#8217;m fine with an unconstrained placeholder.<\/p>\n<p>In the end, as ever, the output of the program. There was no surprise. Concepts behave totally intuitive.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5212\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/conceptsPlaceholder.png\" alt=\"conceptsPlaceholder\" width=\"300\" height=\"154\" style=\"margin: 15px;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/conceptsPlaceholder.png 379w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/03\/conceptsPlaceholder-300x154.png 300w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>That&#8217;s the end of my post. <b>Of course, it&#8217;s not! <\/b>I guess most of you didn&#8217;t recognise that I secretly introduced a new key feature of placeholders. Have a close look at the function <span style=\"font-family: courier new,courier;\">getIntegral<\/span> (line 12).<\/p>\n<div style=\"background: #ffffff none repeat scroll 0% 0%; overflow: auto; width: auto; border-width: 0.1em 0.1em 0.1em 0.8em;\">\n<pre style=\"margin: 0px; line-height: 125%;\">Integral getIntegral(<span style=\"color: #0000ff;\">auto<\/span> val){\r\n  <span style=\"color: #0000ff;\">return<\/span> val;\r\n}\r\n<\/pre>\n<\/div>\n<p>The concept <span style=\"font-family: courier;\">Integral<\/span> as the return type is quite easy to get because it&#8217;s possible to use unconstrained placeholders as return type since C++11. With C++20, we can use &#8211; according to the simple rule &#8211; constrained placeholders. My point is a different one. I use <span style=\"font-family: Courier New,Courier,monospace;\">auto<\/span> for the type of the parameter. That is only possible for generalised lambda functions (see the first example). A generalised lambda function is under the hood a function template. Now, I will come back to my red thread. <strong><span style=\"font-family: courier new,courier;\">getIntegral<\/span> becomes due to the <span style=\"font-family: courier new,courier;\">auto parameter a function template<\/span>.<\/strong>&nbsp; That is happening without the usual function template syntax. <span style=\"font-family: courier new,courier;\">getIntegral<\/span> accepts arbitrary types and returns only values of a type that fulfils the concept <span style=\"font-family: courier;\">Integral<\/span>.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>In the <a href=\"https:\/\/www.modernescpp.com\/index.php\/placeholders-the-second\">next post<\/a>, I will continue my story about placeholders because the unification of templates, concepts, and placeholders goes on.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>C++11 has auto unconstrained placeholders. You can use concepts in C++20 as constrained placeholders. What seems at first glimpse not so thrilling is for me the decisive quantum leap. C++ templates will become an easy to use C++ feature.<\/p>\n","protected":false},"author":21,"featured_media":5209,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[365],"tags":[415],"class_list":["post-5213","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-functional","tag-concepts"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5213","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=5213"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5213\/revisions"}],"predecessor-version":[{"id":6879,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5213\/revisions\/6879"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5209"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5213"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5213"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5213"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}