{"id":5815,"date":"2019-11-21T18:29:55","date_gmt":"2019-11-21T18:29:55","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/concepts-two-extrems-and-the-solution\/"},"modified":"2023-06-26T09:57:45","modified_gmt":"2023-06-26T09:57:45","slug":"concepts-two-extrems-and-the-solution","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/concepts-two-extrems-and-the-solution\/","title":{"rendered":"C++20: Two Extremes and the Rescue with Concepts"},"content":{"rendered":"<p>I finished my overview of C++20 in the last post. Now, it&#8217;s time to dive into the details. What can be a better starting point for our journey than concepts?<\/p>\n<p><!--more--><\/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=\"650\" height=\"254\" 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: 650px) 100vw, 650px\" \/><\/p>\n<p>I must confess: I&#8217;m a big fan of concepts and, therefore, biased. Anyway, let&#8217;s start with a motivating example.<\/p>\n<h2>Two Extremes<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5809\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/TwoExtrems.jpg\" alt=\"TwoExtrems\" width=\"400\" height=\"221\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/TwoExtrems.jpg 663w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/TwoExtrems-300x166.jpg 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>Until C++20, we have in C++ two diametral ways to think about functions or classes. Functions or classes can be defined on specific types or on generic types. In the second case, we call them function or class templates. What is wrong with each way?<\/p>\n<h3>Too Specific<\/h3>\n<p>It&#8217;s quite a job to define a function or class for each specific type. To avoid that burden, type conversion often comes to our rescue. What seems like rescue is often a curse.<\/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;\">\/\/ tooSpecific.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">needInt<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span> i){\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"int: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> i <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\t\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\t\r\n    <span style=\"color: #007788; font-weight: bold;\">double<\/span> d{<span style=\"color: #ff6600;\">1.234<\/span>};                             <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)N<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"double: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> d <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    needInt(d);                                  <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    <span style=\"color: #007788; font-weight: bold;\">bool<\/span> b{<span style=\"color: #336666;\">true<\/span>};                                <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"bool: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> b <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    needInt(b);                                  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n\t\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\t\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>In the first case (line 1), I start with a <span style=\"font-family: courier new, courier;\">double<\/span> and end with an <span style=\"font-family: courier new, courier;\">int<\/span> (line 2). In the second case, I start with a <span style=\"font-family: courier new, courier;\">bool<\/span> (line 3) and also end with an <span style=\"font-family: courier new, courier;\">int<\/span> (line 4).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5810\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/tooSpecific.PNG\" alt=\"tooSpecific\" width=\"300\" height=\"187\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/tooSpecific.PNG 1128w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/tooSpecific-300x187.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/tooSpecific-1024x637.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/tooSpecific-768x478.png 768w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<h4>Narrowing Conversion<\/h4>\n<p>Invoking <code>getInt(int a)<\/code>&nbsp;with a <code>double g<\/code><span>gives you a narrowing conversion. Narrowing conversion is conversion which a loss of accuracy. I assume this is not what you want. <\/span><code> <\/code><\/p>\n<h4>Integral Promotion<\/h4>\n<p>But the other way around is also not better. Invoking <span style=\"font-family: courier new, courier;\">getInt(int a<\/span>) with a <span style=\"font-family: courier new, courier;\">bool<\/span> promotes the <span style=\"font-family: courier new, courier;\">bool<\/span> to <span style=\"font-family: courier new, courier;\">int<\/span>. Surprised? Many C++ developers don&#8217;t know which type they will get when they add to<span style=\"font-family: courier new, courier;\"> boo<\/span>l&#8217;s.<\/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<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> add(T first, T second){\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> first <span style=\"color: #555555;\">+<\/span> second;\r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> main(){\r\n    add(<span style=\"color: #336666;\">true<\/span>, <span style=\"color: #336666;\">false<\/span>);\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p><a href=\"https:\/\/cppinsights.io\/s\/22249b6a\">C++ Insights<\/a> shows you the truth.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5811\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/addGeneric.PNG\" alt=\"addGeneric\" width=\"400\" height=\"279\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/addGeneric.PNG 1281w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/addGeneric-300x209.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/addGeneric-1024x713.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/addGeneric-768x535.png 768w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>The template instantiation of the function template <span style=\"font-family: courier new, courier;\">add<\/span> creates a full specialization (lines 6 &#8211; 12) with the return type <span style=\"font-family: courier new, courier;\">int.<\/span><\/p>\n<p><strong>My firm belief is that we need, for convenience reasons, the entire magic of conversions in C\/C++ to deal with the fact that functions only accept specific types.<\/strong><\/p>\n<p>Okay. Let&#8217;s do it the other way around. Write not specifically, but write generically. Maybe, writing generic code with templates is our rescue.<\/p>\n<h3>Too Generic<\/h3>\n<p>Here is my first try. Sorting is such a generic idea. It should work for each container if the elements of the container are sortable. Let&#8217;s apply <span style=\"font-family: 'courier new', courier;\">std::sor<\/span>t to a <span style=\"font-family: courier new, courier;\">std::list.<\/span><\/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;\">\/\/ sortList.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;algorithm&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;list&gt;<\/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>list<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> myList{<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">10<\/span>, <span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">5<\/span>};\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>sort(myList.begin(), myList.end());\r\n    \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>WOW! This is what you get when I try to compile the small program.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5812\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/sortList.png\" alt=\"sortList\" width=\"600\" height=\"379\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/sortList.png 1697w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/sortList-300x190.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/sortList-1024x648.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/sortList-768x486.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/sortList-1536x972.png 1536w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>I don&#8217;t even want to decipher this message. What is going wrong? Let&#8217;s look closer at the signature of the used overload of <span style=\"font-family: courier new, courier;\">std::sort.<\/span><\/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: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span> <span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">RandomIt<\/span> <span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> sort( RandomIt first, RandomIt last );\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p><span style=\"font-family: courier new, courier;\">std::sort<\/span> uses strange-named arguments such as <span style=\"font-family: courier new, courier;\">RandomIT<\/span>. <span style=\"font-family: courier new, courier;\">RandomIT<\/span> stands for a random access iterator. This is why the overwhelming error message, for which templates are infamous. A <span style=\"font-family: courier new, courier;\">std::list<\/span> provides only a bidirectional iterator, but <span style=\"font-family: courier new, courier;\">std:sort<\/span> requires a random access iterator. The structure of a <span style=\"font-family: courier new, courier;\">std::list<\/span> makes this obvious.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5420\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/04\/list.png\" alt=\"list\" width=\"500\" height=\"35\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/04\/list.png 2249w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/04\/list-300x21.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/04\/list-1024x72.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/04\/list-768x54.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/04\/list-1536x108.png 1536w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/04\/list-2048x144.png 2048w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>When you study carefully the documentation on&nbsp;<a href=\"https:\/\/en.cppreference.com\/w\/cpp\/algorithm\/sort\">cppreference.com<\/a> page to <span style=\"font-family: courier new, courier;\">std::sort<\/span>, you find something exciting: type requirements on <span style=\"font-family: courier new, courier;\">std::sort.<\/span><\/p>\n<\/p>\n<h3>Concepts to the Rescue<\/h3>\n<p>Concepts are the rescue because they put semantic constraints on a template parameter.<\/p>\n<p>Here are the already mentioned type requirements on <span style=\"font-family: courier new, courier;\">std::sort.<\/span><\/p>\n<ul>\n<li>\n<div class=\"spacer\">&nbsp;<code>RandomIt<\/code> must meet the requirements of <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/named_req\/ValueSwappable\"><span style=\"font-family: Georgia, 'DejaVu Serif', serif; font-style: italic;\">ValueSwappable<\/span><\/a> and <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/named_req\/RandomAccessIterator\"><span style=\"font-family: Georgia, 'DejaVu Serif', serif; font-style: italic;\">LegacyRandomAccessIterator<\/span><\/a>.<\/div>\n<\/li>\n<li>The dereferenced <code>RandomIt<\/code> must meet the requirements of <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/named_req\/MoveAssignable\"><span style=\"font-family: Georgia, 'DejaVu Serif', serif; font-style: italic;\">MoveAssignable<\/span><\/a> and <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/named_req\/MoveConstructible\"><span style=\"font-family: Georgia, 'DejaVu Serif', serif; font-style: italic;\">MoveConstructible<\/span><\/a>.<\/li>\n<li>\n<div class=\"spacer\"><code>Compare<\/code> must meet the requirements of <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/named_req\/Compare\">Compare.<\/a><\/div>\n<\/li>\n<\/ul>\n<p>The type requirements on<span style=\"font-family: courier new, courier;\"> std::sort<\/span> are concepts. For a short introduction to concepts, read my post <a href=\"https:\/\/www.modernescpp.com\/index.php\/thebigfour\">C++20: The Big Four<\/a>. In particular, <span style=\"font-family: courier new, courier;\">std::sor<\/span>t requires a <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/named_req\/RandomAccessIterator\" title=\"cpp\/named req\/RandomAccessIterator\"><span style=\"font-family: Georgia, 'DejaVu Serif', serif; font-style: italic;\">LegacyRandomAccessIterator<\/span><\/a>. Let&#8217;s have a closer look at the concept. I polished the example from <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/named_req\/RandomAccessIterator\">cppreference.com<\/a> a little bit.<\/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: 0px; 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> It<span style=\"color: #555555;\">&gt;<\/span>\r\nconcept LegacyRandomAccessIterator <span style=\"color: #555555;\">=<\/span>\r\n  LegacyBidirectionalIterator<span style=\"color: #555555;\">&lt;<\/span>It<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #555555;\">&amp;&amp;        <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span><\/span>\r\n  std<span style=\"color: #555555;\">::<\/span>totally_ordered<span style=\"color: #555555;\">&lt;<\/span>It<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #555555;\">&amp;&amp;<\/span>\r\n  requires(It i, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> std<span style=\"color: #555555;\">::<\/span>incrementable_traits<span style=\"color: #555555;\">&lt;<\/span>It<span style=\"color: #555555;\">&gt;::<\/span>difference_type n) {\r\n    { i <span style=\"color: #555555;\">+=<\/span> n } <span style=\"color: #555555;\">-&gt;<\/span> std<span style=\"color: #555555;\">::<\/span>same_as<span style=\"color: #555555;\">&lt;<\/span>It<span style=\"color: #555555;\">&amp;&gt;<\/span>;        <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n    { i <span style=\"color: #555555;\">-=<\/span> n } <span style=\"color: #555555;\">-&gt;<\/span> std<span style=\"color: #555555;\">::<\/span>same_as<span style=\"color: #555555;\">&lt;<\/span>It<span style=\"color: #555555;\">&amp;&gt;<\/span>;\r\n    { i <span style=\"color: #555555;\">+<\/span>  n } <span style=\"color: #555555;\">-&gt;<\/span> std<span style=\"color: #555555;\">::<\/span>same_as<span style=\"color: #555555;\">&lt;<\/span>It<span style=\"color: #555555;\">&gt;<\/span>;\r\n    { n <span style=\"color: #555555;\">+<\/span>  i } <span style=\"color: #555555;\">-&gt;<\/span> std<span style=\"color: #555555;\">::<\/span>same_as<span style=\"color: #555555;\">&lt;<\/span>It<span style=\"color: #555555;\">&gt;<\/span>;\r\n    { i <span style=\"color: #555555;\">-<\/span>  n } <span style=\"color: #555555;\">-&gt;<\/span> std<span style=\"color: #555555;\">::<\/span>same_as<span style=\"color: #555555;\">&lt;<\/span>It<span style=\"color: #555555;\">&gt;<\/span>;\r\n    { i <span style=\"color: #555555;\">-<\/span>  i } <span style=\"color: #555555;\">-&gt;<\/span> std<span style=\"color: #555555;\">::<\/span>same_as<span style=\"color: #555555;\">&lt;<\/span>decltype(n)<span style=\"color: #555555;\">&gt;<\/span>;\r\n    {  i[n]  } <span style=\"color: #555555;\">-&gt;<\/span> std<span style=\"color: #555555;\">::<\/span>convertible_to<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span><span style=\"color: #007788; font-weight: bold;\">iter_reference_t<\/span><span style=\"color: #555555;\">&lt;<\/span>It<span style=\"color: #555555;\">&gt;&gt;<\/span>;\r\n  };\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Here is the critical observation. A type<span style=\"font-family: courier new, courier;\"> It<\/span> supports LegacyRandomAccessIterator if it supports <span style=\"font-family: courier new, courier;\">LegacyBidirectionalIterator<\/span> (line 2) and all other requirements. For example, the requirement in line 2 means that for a value of type <span style=\"font-family: courier new, courier;\">It:<span style=\"color: #555555;\"><\/span><\/span><span style=\"color: #555555;\"><span style=\"font-family: courier new, courier;\"> <\/span><\/span>{ i += n } is a valid expression, and it returns an<span style=\"font-family: courier new, courier;\"> I&amp;<\/span>. To complete my story, <span style=\"font-family: courier new, courier;\">std::list<\/span> support a <span style=\"font-family: courier new, courier;\">LegacyBidirectionalIterator. <\/span><\/p>\n<p>Admittedly, this section was quite technical. Let&#8217;s try it out. With concepts, you could expect a concise error message such as the following:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5813\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/listError.png\" alt=\"listError\" width=\"400\" height=\"59\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/listError.png 902w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/listError-300x45.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/listError-768x114.png 768w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>Of course, this error message was fake because no compiler implements the C++20 syntax for concepts. MSVC 19.23 support them partially, and GCC is a previous version of concepts. <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/compiler_support\">cppreference.com <\/a>gives more details about the current state of concepts.<\/p>\n<p>Did I mention that GCC supports the previous version of concepts?<\/p>\n<h2>The Long, Long History<\/h2>\n<p>I heard about the first time about concepts around 2005 &#8211; 2006. They reminded me of Haskell type classes. Type classes in Haskell are interfaces for similar types. Here is a part of Haskell type classes hierarchy.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5814\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/haskellsTypeclasses.png\" alt=\"haskellsTypeclasses\" width=\"400\" height=\"345\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/haskellsTypeclasses.png 749w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/haskellsTypeclasses-300x258.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>But C++ concepts are different. Here are a few observations.<\/p>\n<ul>\n<li>In Haskell, a type has to be an instance of a type class. In C++20, a type has to fulfill the requirements of a concept.<\/li>\n<li>Concepts can be used on non-type arguments of templates. For example, numbers such as 5 are non-type arguments. When you want a <span style=\"font-family: courier new, courier;\">std::array<\/span> of <span style=\"font-family: courier new, courier;\">in<\/span>t&#8217;s with five elements, use the non-type argument 5<span style=\"font-family: courier new, courier;\">: std::array&lt;int, 5&gt; myArray.<\/span><\/li>\n<li>Concepts add no run-time costs.<\/li>\n<\/ul>\n<p>Initially, concepts should be the critical feature of <strong>C++11<\/strong>, but they were removed in the standardization meeting in July 2009 in Frankfurt. The quote from Bjarne Stroustrup speaks for itself: &#8220;T<em>he C++Ox concept design evolved into a monster of complexity.<\/em>&#8220;. The next try was unsuccessful a few years later: concepts lite was removed from the <strong>C++17<\/strong> standard. Finally, they are part of <strong>C++20.<\/strong><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>Of course, my <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-20-concepts-the-details\">next post<\/a> is about concepts. I present many examples of what semantic constraints on template parameters mean.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I finished my overview of C++20 in the last post. Now, it&#8217;s time to dive into the details. What can be a better starting point for our journey than concepts?<\/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-5815","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\/5815","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=5815"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5815\/revisions"}],"predecessor-version":[{"id":6765,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5815\/revisions\/6765"}],"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=5815"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5815"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5815"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}