{"id":5828,"date":"2019-12-13T08:59:13","date_gmt":"2019-12-13T08:59:13","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-20-concept-syntactic-sugar\/"},"modified":"2023-06-26T09:56:45","modified_gmt":"2023-06-26T09:56:45","slug":"c-20-concept-syntactic-sugar","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-20-concept-syntactic-sugar\/","title":{"rendered":"C++20: Concepts &#8211; Syntactic Sugar"},"content":{"rendered":"<p>Today, my post is not about something new to concepts. It&#8217;s about syntactic sugar. I write about abbreviated function templates. What? Abbreviated function templates allow a sweet way to define templates.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5808\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/TimelineCpp20Concepts.png\" alt=\"TimelineCpp20Concepts\" width=\"600\" height=\"235\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/TimelineCpp20Concepts.png 954w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/TimelineCpp20Concepts-300x118.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/TimelineCpp20Concepts-768x301.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>First of all, here is the definition of syntactic sugar from <a href=\"https:\/\/en.wikipedia.org\/wiki\/Syntactic_sugar\">Wikipedia<\/a>:<\/p>\n<p><span class=\"st\">In computer science, <em>syntactic sugar<\/em> is <em>syntax<\/em> within a programming language that is designed to make things easier to read or express. It makes the language &#8220;sweeter&#8221; for human use: things can be expressed more clearly, concisely, or in an alternative style that some may prefer.<\/span><\/p>\n<p>The syntactic sugar I&#8217;m writing today is called abbreviated function templates.<\/p>\n<\/p>\n<h2>Abbreviated Function Templates<\/h2>\n<p>I wrote in my last post about concepts <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-20-concepts-the-placeholder-syntax\">C++20: Concepts, the Placeholder Syntax<\/a> that we have had since C++14, a significant asymmetry: generic lambdas introduced a new way to define function templates. Just use <span style=\"font-family: courier new, courier;\">auto<\/span> as a function parameter. On the contrary, you can not use <span style=\"font-family: courier new, courier;\">auto<\/span> as a function parameter to get a function template.<\/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;\">\/\/ genericLambdaFunction.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\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> addLambda <span style=\"color: #555555;\">=<\/span> [](<span style=\"color: #006699; font-weight: bold;\">auto<\/span> fir, <span style=\"color: #006699; font-weight: bold;\">auto<\/span> sec){ <span style=\"color: #006699; font-weight: bold;\">return<\/span> fir <span style=\"color: #555555;\">+<\/span> sec; }; <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> <span style=\"color: #cc00ff;\">addFunction<\/span>(<span style=\"color: #006699; font-weight: bold;\">auto<\/span> fir, <span style=\"color: #006699; font-weight: bold;\">auto<\/span> sec){ <span style=\"color: #006699; font-weight: bold;\">return<\/span> fir <span style=\"color: #555555;\">+<\/span> sec; }     <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    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>boolalpha <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> addLambda(<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">5<\/span>) <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> addFunction(<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">5<\/span>) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> addLambda(<span style=\"color: #336666;\">true<\/span>, <span style=\"color: #ff6600;\">5<\/span>) <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> addFunction(<span style=\"color: #336666;\">true<\/span>, <span style=\"color: #ff6600;\">5<\/span>) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> addLambda(<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">5.5<\/span>) <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> addFunction(<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">5.5<\/span>) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n    <span style=\"color: #006699; font-weight: bold;\">const<\/span> std<span style=\"color: #555555;\">::<\/span>string fir{<span style=\"color: #cc3300;\">\"ge\"<\/span>};\r\n    <span style=\"color: #006699; font-weight: bold;\">const<\/span> std<span style=\"color: #555555;\">::<\/span>string sec{<span style=\"color: #cc3300;\">\"neric\"<\/span>};\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> addLambda(fir, sec) <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> addFunction(fir, sec) <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>&nbsp;The Clang compiler speaks clear language when I try to compile this program with the C++14 standard.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5824\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/12\/genericLambdaFunction.png\" alt=\"genericLambdaFunction\" width=\"500\" height=\"164\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/12\/genericLambdaFunction.png 847w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/12\/genericLambdaFunction-300x98.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/12\/genericLambdaFunction-768x252.png 768w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>How strange! I can use <span style=\"font-family: courier new, courier;\">auto<\/span> as the return type and for the function parameters in a lambda (line 1), but I can only use <span style=\"font-family: courier new, courier;\">auto<\/span> as the return type of a function (line 2).<\/p>\n<p>I&#8217;m happy to say. This weird behavior is gone with C++20, and the unification is extended to concepts.<\/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: #0099ff; font-style: italic;\">\/\/ conceptsIntegralVariationsDraft.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;type_traits&gt;<\/span>\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: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>                                  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\nconcept Integral <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>is_integral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value;       \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>                                  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\nrequires Integral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span>\r\nT gcd(T a, T b){\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span>( b <span style=\"color: #555555;\">==<\/span> <span style=\"color: #ff6600;\">0<\/span> ) <span style=\"color: #006699; font-weight: bold;\">return<\/span> a;\r\n    <span style=\"color: #006699; font-weight: bold;\">else<\/span> <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #cc00ff;\">gcd<\/span>(b, a <span style=\"color: #555555;\">%<\/span> b);\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>                                  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\nT gcd1(T a, T b) requires Integral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span>{\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span>( b <span style=\"color: #555555;\">==<\/span> <span style=\"color: #ff6600;\">0<\/span> ){ <span style=\"color: #006699; font-weight: bold;\">return<\/span> a; }\r\n    <span style=\"color: #006699; font-weight: bold;\">else<\/span> <span style=\"color: #006699; font-weight: bold;\">return<\/span> gcd(b, a <span style=\"color: #555555;\">%<\/span> b);\r\n}\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span>Integral T<span style=\"color: #555555;\">&gt;<\/span>                                  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\nT gcd2(T a, T b){\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span>( b <span style=\"color: #555555;\">==<\/span> <span style=\"color: #ff6600;\">0<\/span> ){ <span style=\"color: #006699; font-weight: bold;\">return<\/span> a; }\r\n    <span style=\"color: #006699; font-weight: bold;\">else<\/span> <span style=\"color: #006699; font-weight: bold;\">return<\/span> gcd(b, a <span style=\"color: #555555;\">%<\/span> b);\r\n}\r\n\r\nIntegral <span style=\"color: #006699; font-weight: bold;\">auto<\/span> gcd3(Integral <span style=\"color: #006699; font-weight: bold;\">auto<\/span> a, Integral <span style=\"color: #006699; font-weight: bold;\">auto<\/span> b){ <span style=\"color: #0099ff; font-style: italic;\">\/\/ (5)<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span>( b <span style=\"color: #555555;\">==<\/span> <span style=\"color: #ff6600;\">0<\/span> ){ <span style=\"color: #006699; font-weight: bold;\">return<\/span> a; }\r\n    <span style=\"color: #006699; font-weight: bold;\">else<\/span> <span style=\"color: #006699; font-weight: bold;\">return<\/span> gcd(b, a <span style=\"color: #555555;\">%<\/span> b);\r\n}\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> gcd4(<span style=\"color: #006699; font-weight: bold;\">auto<\/span> a, <span style=\"color: #006699; font-weight: bold;\">auto<\/span> b){                            <span style=\"color: #0099ff; font-style: italic;\">\/\/ (6)<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span>( b <span style=\"color: #555555;\">==<\/span> <span style=\"color: #ff6600;\">0<\/span> ){ <span style=\"color: #006699; font-weight: bold;\">return<\/span> a; }\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> gcd(b, a <span style=\"color: #555555;\">%<\/span> b);\r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> main(){\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;\">\"gcd(100, 10)= \"<\/span>  <span style=\"color: #555555;\">&lt;&lt;<\/span>  gcd(<span style=\"color: #ff6600;\">100<\/span>, <span style=\"color: #ff6600;\">10<\/span>)  <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"gcd1(100, 10)= \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span>  gcd1(<span style=\"color: #ff6600;\">100<\/span>, <span style=\"color: #ff6600;\">10<\/span>)  <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"gcd2(100, 10)= \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span>  gcd2(<span style=\"color: #ff6600;\">100<\/span>, <span style=\"color: #ff6600;\">10<\/span>)  <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"gcd3(100, 10)= \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span>  gcd3(<span style=\"color: #ff6600;\">100<\/span>, <span style=\"color: #ff6600;\">10<\/span>)  <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"gcd4(100, 10)= \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span>  gcd3(<span style=\"color: #ff6600;\">100<\/span>, <span style=\"color: #ff6600;\">10<\/span>)  <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>Let me describe in a few words the already known stuff for my previous posts to concepts. Line 1 defines the concept <span style=\"font-family: courier new, courier;\">Integral<\/span>. <span style=\"font-family: courier new, courier;\">gcd &#8211; gcd2<\/span>&nbsp;(lines 2 &#8211; 4) use the concept in various ways. <span style=\"font-family: courier new, courier;\">gcd<\/span>&nbsp;used the required clause, <span style=\"font-family: courier new, courier;\">gcd1&nbsp;<\/span>the so-called trailing requires clause, and <span style=\"font-family: courier new, courier;\">gcd2<\/span>&nbsp;constrained template parameters.<\/p>\n<p>With <span style=\"font-family: courier new, courier;\">gcd3<\/span>, the syntactic sugar starts. The function declaration <span style=\"color: #000000; font-family: courier new, courier;\">Integral auto gcd3(Integral auto a, Integral auto b)<\/span> requires from its type parameters that they support the concept <span style=\"font-family: courier new, courier;\">Integral. <\/span>This syntactic form is the new way to use a concept and get a function template equivalent to the previous versions<span style=\"font-family: courier new, courier;\"> <\/span>gcd &#8211; gcd2.<\/p>\n<p>The syntactic form of gcd3 and gcd4 is called <strong>abbreviated function templates<\/strong>. <span style=\"font-family: courier new, courier;\">Integral auto<\/span> in the declaration of <span style=\"font-family: courier new, courier;\">gcd3<\/span> is a&nbsp; constrained placeholder (concept), but you can also use an unconstrained placeholder <span style=\"font-family: courier new, courier;\">(auto)<\/span>&nbsp; in a function declaration such as in <span style=\"font-family: courier new, courier;\">gcd4<\/span> (line 6). Before I make a few additional remarks to this new syntax, here is the output of the program:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5825\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/12\/conceptsIntegralVariationsDraft.png\" alt=\"conceptsIntegralVariationsDraft\" width=\"400\" height=\"191\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/12\/conceptsIntegralVariationsDraft.png 582w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/12\/conceptsIntegralVariationsDraft-300x143.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>An unconstrained placeholder <span style=\"font-family: courier new, courier;\">(auto)<\/span> in a function declaration generates a function template. The following two functions <span style=\"font-family: courier new, courier;\">add<\/span> are equivalent:<\/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: #006699; font-weight: bold;\">typename<\/span> T2<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> add(T fir, T2 sec){\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> fir <span style=\"color: #555555;\">+<\/span> sec;\r\n}\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> add(<span style=\"color: #006699; font-weight: bold;\">auto<\/span> fir, <span style=\"color: #006699; font-weight: bold;\">auto<\/span> sec){\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> fir <span style=\"color: #555555;\">+<\/span> sec;\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The critical observation is that both arguments can have different types. The same holds for concepts.<\/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>Arithmetic T, Arithmetic T2<span style=\"color: #555555;\">&gt;                           <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span><\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> sub(T fir, T2 sec){\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> fir <span style=\"color: #555555;\">-<\/span> sec;\r\n}\r\n\r\nArithmetic <span style=\"color: #006699; font-weight: bold;\">auto<\/span> sub(Arithmetic <span style=\"color: #006699; font-weight: bold;\">auto<\/span> fir, Arithmetic <span style=\"color: #006699; font-weight: bold;\">auto<\/span> sec){  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> fir <span style=\"color: #555555;\">-<\/span> sec;\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The function <span style=\"font-family: courier new, courier;\">sub<\/span> requires from its arguments <span style=\"font-family: courier new, courier;\">fir<\/span> and <span style=\"font-family: courier new, courier;\">sec,<\/span>&nbsp; that both support the concept <span style=\"font-family: courier new, courier;\">Arithmetic. <\/span>This means you can invoke <span style=\"font-family: courier new, courier;\">sub(5.5, 5),<\/span> and it works with the function template (line 1) and the function (line 2). The return type is deduced according to arithmetic conversion rules in both cases. The concept <span style=\"font-family: courier new, courier;\">Arithmetic<\/span> requires that <span style=\"font-family: courier new, courier;\">fir<\/span> and <span style=\"font-family: courier new, courier;\">sec<\/span> are either integral or floating-point numbers. Here is a straightforward implementation based on the type-traits function <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/types\/is_arithmetic\"><span style=\"font-family: courier new, courier;\">std::is_arithmetic<\/span><\/a>.<\/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\nconcept Arithmetic <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>is_arithmetic<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value; \r\n<\/pre>\n<\/div>\n<h3>A Difference between Concepts TS and Concepts Draft<\/h3>\n<p>I explicitly mentioned that both arguments could have different types with the Concepts Draft because this is different from the previous concepts syntax, supported by GCC. The previous syntax was based on the concepts TS (technical specification). In this syntax, the types of <span style=\"font-family: courier new, courier;\">fir<\/span> and <span style=\"font-family: courier new, courier;\">sec<\/span> have to be the same, and a call of the function&nbsp;<span style=\"font-family: courier new, courier;\">sub(5.5, 5)<\/span> would fail. Additionally, the previous syntax required no additional <span style=\"font-family: courier new, courier;\">auto<\/span> when concepts were used, and the definition of concepts was slightly more verbose.<\/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;\">\/\/ conceptsArithmeticTS.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;type_traits&gt;<\/span>\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: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>\r\nconcept <span style=\"color: #007788; font-weight: bold;\">bool<\/span> Arithmetic(){\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> std<span style=\"color: #555555;\">::<\/span>is_arithmetic<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value;\r\n}\r\n\r\nArithmetic sub(Arithmetic fir, Arithmetic sec){\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> fir <span style=\"color: #555555;\">-<\/span> sec;\r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> main(){\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;\">\"sub(6, 5): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> sub(<span style=\"color: #ff6600;\">6<\/span>, <span style=\"color: #ff6600;\">5<\/span>) <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;\">\"sub(5.5, 5): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> sub(<span style=\"color: #ff6600;\">5.5<\/span>, <span style=\"color: #ff6600;\">5<\/span>) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/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>Because of line 2, the compilation of the program fails with the concepts TS.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5826\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/12\/conceptsArithmeticTS.png\" alt=\"conceptsArithmeticTS\" width=\"600\" height=\"157\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/12\/conceptsArithmeticTS.png 1490w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/12\/conceptsArithmeticTS-300x79.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/12\/conceptsArithmeticTS-1024x268.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/12\/conceptsArithmeticTS-768x201.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<h3>Overloading<\/h3>\n<p>The abbreviated function templates syntax behaves as expected. The new syntax support overloading.&nbsp;As usual, the compiler chooses the best-fitting overload.<\/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;\">\/\/ conceptsOverloading.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;type_traits&gt;<\/span>\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: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>\r\nconcept Integral <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>is_integral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value;\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">overload<\/span>(<span style=\"color: #006699; font-weight: bold;\">auto<\/span> t){\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"auto : \"<\/span> <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<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">overload<\/span>(Integral <span style=\"color: #006699; font-weight: bold;\">auto<\/span> t){\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Integral : \"<\/span> <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<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">overload<\/span>(<span style=\"color: #007788; font-weight: bold;\">long<\/span> t){\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"long : \"<\/span> <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<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    overload(<span style=\"color: #ff6600;\">3.14<\/span>);             <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n    overload(<span style=\"color: #ff6600;\">2010<\/span>);             <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n    overload(<span style=\"color: #ff6600;\">2020l<\/span>);            <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/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>When invoked with a <span style=\"font-family: 'courier new', courier;\">double<\/span> (line 1), an <span style=\"font-family: courier new, courier;\">int (<\/span>line 2<span style=\"font-family: courier new, courier;\">),<\/span> or a <span style=\"font-family: courier new, courier;\">long int (<span style=\"font-family: 'andale mono', times;\">line 3<\/span>)<\/span>, the best-fitting overload is chosen.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5827\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/12\/conceptOverloading.png\" alt=\"conceptOverloading\" width=\"300\" height=\"171\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/12\/conceptOverloading.png 478w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/12\/conceptOverloading-300x171.png 300w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>Two pieces are still missing in my series of concepts and are, therefore, the topic of my <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-20-concepts-what-we-dont-get\">next posts<\/a> \u2014 the definition of concepts and the so-called template introduction, which is part of the concept TS.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today, my post is not about something new to concepts. It&#8217;s about syntactic sugar. I write about abbreviated function templates. What? Abbreviated function templates allow a sweet way to define templates.<\/p>\n","protected":false},"author":21,"featured_media":5808,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[375],"tags":[415],"class_list":["post-5828","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c-20","tag-concepts"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5828","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=5828"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5828\/revisions"}],"predecessor-version":[{"id":6762,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5828\/revisions\/6762"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5808"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5828"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5828"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5828"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}