{"id":5171,"date":"2017-02-08T21:35:16","date_gmt":"2017-02-08T21:35:16","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/concepts-lite\/"},"modified":"2023-06-26T12:24:07","modified_gmt":"2023-06-26T12:24:07","slug":"concepts-lite","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/concepts-lite\/","title":{"rendered":"Concepts"},"content":{"rendered":"<p>We stay in the year 2020. With high probability, we will get concepts. Of course, waterproof statements about the future are challenging, but the statement is from Bjarne Stroustrup (<a href=\"http:\/\/meetingcpp.com\/index.php\/mcpp2016.html\">Meeting C++ 2016<\/a> at Berlin).<\/p>\n<p><!--more--><\/p>\n<h2>The classical concepts<\/h2>\n<p>The key idea of generic programming with templates is to define functions and classes that can be used with different types. But it will often happen that you instantiate a template with the wrong type. The result may be a cryptic error message that is many pages long. Sadly to say, templates in C++ are known for this. Therefore, classical concepts were planned as one of the great features of C++11. They should allow you to specify constraints for templates that the compiler can verify. Thanks to their complexity, they were removed in July 2009 from the standard:&nbsp; &#8220;The C++0x concept design evolved into a monster of complexity.&#8221; (Bjarne Stroustrup)<\/p>\n<\/p>\n<h2>Concepts<\/h2>\n<p>With C++20 we will get concepts. Although concepts are in the first implementations of simplified classical concepts, they have much to offer.<\/p>\n<p>They<\/p>\n<ol>\n<li>empower the programmer to express their requirements as part of the interface directly.<\/li>\n<li>support the overloading of functions and the specialization of class templates based on the requirements of the template parameters.<\/li>\n<li>produce drastically improved error messages by comparing the requirements of the template parameter with the applied template arguments.<\/li>\n<li>can be used as placeholders for generic programming.<\/li>\n<li>empower you to define your own concepts.<\/li>\n<\/ol>\n<p><em>Although concepts are sometimes called concepts lite, their functionality is by no means lite and I can not be presented in one post. Therefore, I will postpone points 4 and 5 to later posts. Promised!<br \/><\/em><\/p>\n<p>You will benefit without additional compile-time or runtime time of the program. Concepts are similar to Haskell&#8217;s type classes. Concepts will describe semantic categories and not syntactic restrictions. For standard library types, we get <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/concept\">library concepts<\/a> such as <span style=\"font-family: courier new,courier;\">DefaultConstructible, MoveConstructible, CopyConstructible, MoveAssignable, CopyAssignable<\/span>,&nbsp; or <span style=\"font-family: courier        new,courier;\">Destructible<\/span>. For the containers, we get concepts such as <span style=\"font-family: courier new,courier;\">ReversibleContainer, AllocatorAwareContainer, SequenceContainer, ContinousContainer, AssociativeContainer<\/span>, or <span style=\"font-family: couriernew,courier;\">UnorderedAssociativeContainer<\/span>. You can read the about concepts and their constraints here: <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/concept\">cppreference.com<\/a>.<\/p>\n<p>Before I present concepts, let me have a view of Haskell&#8217;s type classes.<\/p>\n<h3>Type classes in Haskell<\/h3>\n<p>Type classes are interfaces for similar types. If a type is a member of a type class, it has to have specific properties. Type classes play a similar role in generic programming as interfaces play in object-oriented programming. Here you can see a part of Haskell&#8217;s type classes hierarchy.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5169\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/typeclass.png\" alt=\"typeclass\" style=\"margin: 15px;\" width=\"542\" height=\"460\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/typeclass.png 542w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/typeclass-300x255.png 300w\" sizes=\"auto, (max-width: 542px) 100vw, 542px\" \/><\/p>\n<p>What is unique for a type if it is a member of a type class<span style=\"font-family: courier new;\"> Eq<\/span>? <span style=\"font-family: courier new;\">Eq<\/span> stands for equality and requires from its members:<\/p>\n<p>&nbsp;<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">Eq<\/span> a <span style=\"color: #0000ff;\">where<\/span>\r\n    (==) <span style=\"color: #0000ff;\">::<\/span> a <span style=\"color: #0000ff;\">-&gt;<\/span> a <span style=\"color: #0000ff;\">-&gt;<\/span> <span style=\"color: #2b91af;\">Bool<\/span>\r\n    (\/=) <span style=\"color: #0000ff;\">::<\/span> a <span style=\"color: #0000ff;\">-&gt;<\/span> a <span style=\"color: #0000ff;\">-&gt;<\/span> <span style=\"color: #2b91af;\">Bool<\/span>\r\n    a == b <span style=\"color: #0000ff;\">=<\/span> not (a \/= b)\r\n    a \/= b <span style=\"color: #0000ff;\">=<\/span> not (a == b)\r\n<\/pre>\n<\/div>\n<p><span style=\"font-family: courier new,courier;\">Eq<\/span> requires that its types support the functions equality (<span style=\"font-family: courier new,courier;\">==<\/span>) and inequality (<span style=\"font-family: courier new,courier;\">\/=)<\/span>. The expression <span style=\"font-family: courier new,courier;\">a -&gt; a -&gt; Bool<\/span> stands for the function&#8217;s signature. The function takes two identical types <span style=\"font-family: courier new,courier;\">a<\/span> and returns a Boolean: <span style=\"font-family: courier new,courier;\">Bool<\/span>. But for a concrete type, it is sufficient to implement equality or inequality because equality will be mapped to inequality and vice versa. The default implementations of both functions are provided in the two last lines.<\/p>\n<p>By the following code snipped, the built-in type <span style=\"font-family: courier new,courier;\">Bool<\/span> becomes an instance of the type class <span style=\"font-family: courier        new,courier;\">Eq<\/span>.<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0000ff;\">instance<\/span> <span style=\"color: #2b91af;\">Eq<\/span> <span style=\"color: #2b91af;\">Bool<\/span> <span style=\"color: #0000ff;\">where<\/span>\r\n    <span style=\"color: #2b91af;\">True<\/span> == <span style=\"color: #2b91af;\">True<\/span> <span style=\"color: #0000ff;\">=<\/span> <span style=\"color: #2b91af;\">True<\/span>\r\n    <span style=\"color: #2b91af;\">False<\/span> == <span style=\"color: #2b91af;\">False<\/span> <span style=\"color: #0000ff;\">=<\/span> <span style=\"color: #2b91af;\">True<\/span>\r\n    <span style=\"color: #0000ff;\">_<\/span> == <span style=\"color: #0000ff;\">_<\/span> <span style=\"color: #0000ff;\">=<\/span> <span style=\"color: #2b91af;\">False<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Haskell&#8217;s type classes build a hierarchy. The type class&nbsp; <span style=\"font-family: courier new,courier;\">Ord<\/span> is a subclass of the type class<span style=\"font-family: courier new,courier;\"> Eq.<\/span> Therefore, instances of the type class <span style=\"font-family: courier new,courier;\">Ord<\/span> have to be members of the type class <span style=\"font-family: courier        new,courier;\">Eq<\/span> and have, in addition, support the comparison operators.<\/p>\n<p>Haskell can automatically create the necessary functions of some class types. Therefore, I can compare the values <span style=\"font-family: courier new;\">Morning <\/span>and <span style=\"font-family: courier new;\">Afternoon <\/span>of the data type day for equality and output them. I have only to derive Day from the type class <span style=\"font-family: courier new;\">Eq <\/span>and <span style=\"font-family: courier new;\">Show<\/span>.<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0000ff;\">data<\/span> <span style=\"color: #2b91af;\">Day<\/span><span style=\"color: #0000ff;\">=<\/span> <span style=\"color: #2b91af;\">Morning<\/span> | <span style=\"color: #2b91af;\">Afternoon<\/span>\r\n     <span style=\"color: #0000ff;\">deriving<\/span> (<span style=\"color: #2b91af;\">Eq<\/span>,<span style=\"color: #2b91af;\">Show<\/span>)\r\n<\/pre>\n<\/div>\n<p>I can directly test my data type <span style=\"font-family: courier new;\">Day <\/span>in the interactive Haskell Shell. The formal name for the interactive Shell is REPL. Many programming languages, such as Python or Perl, have a REPL. REPL stands for <strong>R<\/strong>ead <strong>E<\/strong>valuate <strong>P<\/strong>rint <strong>L<\/strong>oop<strong>.<\/strong><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5170\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/day.png\" alt=\"day\" width=\"600\" height=\"322\" style=\"margin: 15px;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/day.png 624w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/day-300x161.png 300w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>Type classes in Haskell have a lot more to offer. For example, you can define your own class.<\/p>\n<h3>Concepts for functions, classes, and members of a class<\/h3>\n<p>Concepts are part of the template declaration.<\/p>\n<h4>Functions<\/h4>\n<p>The function template <span style=\"font-family: courier new,courier;\">sort<\/span> requires<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0000ff;\">template<\/span>&lt;Sortable Cont&gt;\r\n<span style=\"color: #2b91af;\">void<\/span> sort(Cont&amp; container){...}\r\n\r\n<\/pre>\n<\/div>\n<p>that the container has to be <span style=\"font-family: courier new,courier;\">Sortable<\/span>. It is also possible to define the requirement for the template parameters more explicitly:<\/p>\n<p>&nbsp;<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0000ff;\">template<\/span>&lt;<span style=\"color: #0000ff;\">typename<\/span> Cont&gt;\r\n  requires Sortable&lt;Cont&gt;()\r\n<span style=\"color: #2b91af;\">void<\/span> sort(Cont&amp; container){...}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p><span style=\"font-family: courier new,courier;\">Sortable<\/span> has to be a constant expression that is a predicate. That means that the expression must be evaluable at compile time and return a boolean.<\/p>\n<p>If you invoke the sort algorithm with a container <span style=\"font-family: courier new;\">lst <\/span>that is not sortable, you will have a unique error message from the compiler.<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\">std::list&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; lst = {1998,2014,2003,2011};\r\nsort(lst); <span style=\"color: #008000;\">\/\/ ERROR: lst is no random-access container with &lt;<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>You can use concepts for all kinds of templates.<\/p>\n<h4>Classes<\/h4>\n<p>Therefore, you can define a class template <span style=\"font-family: courier new,courier;\">MyVector<\/span> that will only accept objects as template arguments:<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0000ff;\">template<\/span>&lt;Object T&gt;\r\n<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">MyVector<\/span>{};\r\n\r\nMyVector&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; v1; <span style=\"color: #008000;\">\/\/ OK<\/span>\r\nMyVector&lt;<span style=\"color: #2b91af;\">int<\/span>&amp;&gt; v2 <span style=\"color: #008000;\">\/\/ ERROR: int&amp; does not satisfy the constraint Object<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Now, the compiler complains that the pointer <span style=\"font-family: courier new,courier;\">(int&amp;<\/span>)&nbsp; is no object. <span style=\"font-family: courier new,courier;\">MyClass<\/span> can be further adjusted.<\/p>\n<h4>Members of a class<\/h4>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0000ff;\">template<\/span>&lt;Object T&gt;\r\n<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">MyVector<\/span>{\r\n  ...\r\n  requires Copyable&lt;T&gt;()\r\n  <span style=\"color: #2b91af;\">void<\/span> push_back(<span style=\"color: #0000ff;\">const<\/span> T&amp; e);\r\n  ...\r\n};\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Now the method&nbsp; <span style=\"font-family: courier new,courier;\">push_back<\/span>&nbsp; from <span style=\"font-family: courier new,courier;\">MyVector <span style=\"font-family: Helvetica,Arial,sans-serif;\">requires that the template argument has to be copyable.<\/span><\/span><\/p>\n<h3>Extended functionality<\/h3>\n<p>A template can have more than one requirement for its template parameters.<\/p>\n<h4>More than one requirement<\/h4>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0000ff;\">template<\/span> &lt;SequenceContainer S,EqualityComparable&lt;value_type&lt;S&gt;&gt; T&gt;\r\nIterator_type&lt;S&gt; find(S&amp;&amp; seq, <span style=\"color: #0000ff;\">const<\/span> T&amp; val){...}\r\n<\/pre>\n<\/div>\n<p>The function template find has two requirements. On the one hand, the container has to store its elements in a linear arrangement (<span style=\"font-family: courier new,courier;\">SequenceContainer<\/span>); on the other hand, the elements of the container have to be equality comparable: <span style=\"font-family: courier new,courier;\">EqualityComparable&lt;value_type&lt;S&gt;&gt;<\/span>).<\/p>\n<p>Concepts support the overloading of functions.<\/p>\n<h4>Overloading of functions<\/h4>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0000ff;\">template<\/span>&lt;InputIterator I&gt;\r\n<span style=\"color: #2b91af;\">void<\/span> advance(I&amp; iter, <span style=\"color: #2b91af;\">int<\/span> n){...}\r\n\r\n<span style=\"color: #0000ff;\">template<\/span>&lt;BidirectionalIterator I&gt;\r\n<span style=\"color: #2b91af;\">void<\/span> advance(I&amp; iter, <span style=\"color: #2b91af;\">int<\/span> n){...}\r\n\r\n<span style=\"color: #0000ff;\">template<\/span>&lt;RandomAccessIterator I&gt;\r\n<span style=\"color: #2b91af;\">void<\/span> advance(I&amp; iter, <span style=\"color: #2b91af;\">int<\/span> n){...}\r\n\r\nstd::list&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; lst{1,2,3,4,5,6,7,8,9};\r\nstd::list&lt;<span style=\"color: #2b91af;\">int<\/span>&gt;:: iterator i= lst.begin();\r\nstd::advance(i,2);   <span style=\"color: #008000;\">\/\/ BidirectionalIterator<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The function template <span style=\"font-family: courier new,courier;\">advance<\/span> puts its&#8217;s iterator <span style=\"font-family: courier new,courier;\">iter<\/span> <span style=\"font-family: courier new,courier;\">n<\/span> positions further. Different function templates will be applied depending on whether the iterator is a forward, a bi-directional, or a random access iterator. If I use a std::list, the <span style=\"font-family: courier new,courier;\">BidirectionalIterator<\/span> will be chosen.<\/p>\n<p>Concepts also support the specialization of class templates.<\/p>\n<h4>The specialization of class templates<\/h4>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0000ff;\">template<\/span>&lt;<span style=\"color: #0000ff;\">typename<\/span> T&gt;\r\n<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">MyVector<\/span>{};\r\n\r\n<span style=\"color: #0000ff;\">template<\/span>&lt;Object T&gt;\r\n<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">MyVector<\/span>{};\r\n\r\nMyVector&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; v1; <span style=\"color: #008000;\">\/\/ Object T<\/span>\r\nMyVector&lt;<span style=\"color: #2b91af;\">int<\/span>&amp;&gt; v2 <span style=\"color: #008000;\">\/\/ typename T<\/span>\r\n<\/pre>\n<\/div>\n<p>Therefore, the compiler maps <span style=\"font-family: courier new,courier;\">MyVector&lt;int&amp;&gt; v2<\/span> to the general template in the first line; the compiler maps <span style=\"font-family: courier new,courier;\">MyVector&lt;int&gt; v1<\/span> on the contrary to the specialization <span style=\"font-family: courier new,courier;\">template&lt;Object T&gt; class MyVector{}.<\/span><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>Haskell has the type class <span style=\"font-family: courier new;\">Monad<\/span>.&nbsp; A known instance is the <span style=\"font-family: courier new;\">Maybe Monad<\/span>. Why did I write about that stuff? That is simple. C++17 gets with the data type <span style=\"font-family: courier new;\">std::optiona<\/span>l a <span style=\"font-family: courier new;\">Monad<\/span> that represents a calculation that can or can not return a result. The details about <span style=\"font-family: courier new,courier;\">std::optional<\/span> will follow in the <a href=\"https:\/\/www.modernescpp.com\/index.php\/monads-in-c\">next post<\/a>.&nbsp;&nbsp; <span id=\"transmark\"><br \/><\/span><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>We stay in the year 2020. With high probability, we will get concepts. Of course, waterproof statements about the future are challenging, but the statement is from Bjarne Stroustrup (Meeting C++ 2016 at Berlin).<\/p>\n","protected":false},"author":21,"featured_media":5169,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[365],"tags":[415,508],"class_list":["post-5171","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-functional","tag-concepts","tag-haskell"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5171","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=5171"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5171\/revisions"}],"predecessor-version":[{"id":6890,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5171\/revisions\/6890"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5169"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5171"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5171"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5171"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}