{"id":5538,"date":"2018-10-25T17:02:26","date_gmt":"2018-10-25T17:02:26","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-definition-of-concepts-the-second\/"},"modified":"2023-06-26T11:42:48","modified_gmt":"2023-06-26T11:42:48","slug":"c-core-guidelines-definition-of-concepts-the-second","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-definition-of-concepts-the-second\/","title":{"rendered":"C++ Core Guidelines: Definition of Concepts, the Second"},"content":{"rendered":"<p>Let me continue with the rules for defining concepts in the guidelines. The first of the three remaining rules in this post is quite sophisticated.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5534\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/fern-821293_1280.jpg\" alt=\"fern 821293 1280\" width=\"600\" height=\"373\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/fern-821293_1280.jpg 1280w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/fern-821293_1280-300x186.jpg 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/fern-821293_1280-1024x636.jpg 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/fern-821293_1280-768x477.jpg 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>&nbsp;Here are the rules for today:<\/p>\n<ul>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-tag\" style=\"color: #268bd2; text-decoration: none;\">T.24: Use tag classes or traits to differentiate concepts that differ only in semantics<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-not\" style=\"color: #268bd2; text-decoration: none;\">T.25: Avoid complimentary constraints<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-use\" style=\"color: #268bd2; text-decoration: none;\">T.26: Prefer to define concepts in terms of use-patterns rather than simple syntax<\/a><\/li>\n<\/ul>\n<p>The explanation of the first rules is relatively concise. Maybe, too concise.<\/p>\n<\/p>\n<h2><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-tag\" style=\"color: #268bd2; text-decoration: none;\">T.24: Use tag classes or traits to differentiate concepts that differ only in semantics<\/a><\/h2>\n<p>This is the reason for this rule from the guidelines: &#8220;Two concepts requiring the same syntax but having different semantics leads to ambiguity unless the programmer differentiates them.&#8221;<\/p>\n<p>Let&#8217;s assume; I defined the <span style=\"font-family: 'courier new', courier;\">is_contiguous<\/span> trait. In this case, I can use it to distinguish a random access iterator<span style=\"font-family: 'courier new', courier;\"> RA_iter<\/span> from a contiguous iterator <span style=\"font-family: 'courier new', courier;\">Contiguous_iter<\/span>.<\/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> I<span style=\"color: #555555;\">&gt;<\/span>    <span style=\"color: #0099ff; font-style: italic;\">\/\/ iterator providing random access<\/span>\r\nconcept <span style=\"color: #007788; font-weight: bold;\">bool<\/span> RA_iter <span style=\"color: #555555;\">=<\/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> I<span style=\"color: #555555;\">&gt;<\/span>    <span style=\"color: #0099ff; font-style: italic;\">\/\/ iterator providing random access to contiguous data<\/span>\r\nconcept <span style=\"color: #007788; font-weight: bold;\">bool<\/span> Contiguous_iter <span style=\"color: #555555;\">=<\/span>\r\n    RA_iter<span style=\"color: #555555;\">&lt;<\/span>I<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #555555;\">&amp;&amp;<\/span> is_contiguous<span style=\"color: #555555;\">&lt;<\/span>I<span style=\"color: #555555;\">&gt;::<\/span>value;  <span style=\"color: #0099ff; font-style: italic;\">\/\/ using is_contiguous trait<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>I can even use a tag class such as is_contiguous into a concept. Now, I have a more straightforward expression of my idea of contiguous iterator <span style=\"font-family: 'courier new', courier;\">Contiguous_iter<\/span>.<\/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> I<span style=\"color: #555555;\">&gt;<\/span> concept Contiguous <span style=\"color: #555555;\">=<\/span> is_contiguous<span style=\"color: #555555;\">&lt;<\/span>I<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> I<span style=\"color: #555555;\">&gt;<\/span>\r\nconcept <span style=\"color: #007788; font-weight: bold;\">bool<\/span> Contiguous_iter <span style=\"color: #555555;\">=<\/span> RA_iter<span style=\"color: #555555;\">&lt;<\/span>I<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #555555;\">&amp;&amp;<\/span> Contiguous<span style=\"color: #555555;\">&lt;<\/span>I<span style=\"color: #555555;\">&gt;<\/span>;\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Okay, let me explain two key terms: traits and tag dispatching.<\/p>\n<h3>Traits<\/h3>\n<p>Traits are class templates that extract properties from a generic type.&nbsp;<\/p>\n<p>The following program&nbsp;presents a type that satisfies the specific trait for each of the 14 primary type categories of the type-traits library. The primary type categories are complete and don\u2019t overlap. So each type is a member of a type category. If you check a type category for your type, the request is independent of the <span style=\"font-family: 'courier new', courier;\">const<\/span> or <span style=\"font-family: 'courier new', courier;\">volatile<\/span> qualifiers.<\/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;\">\/\/ traitsPrimary.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;type_traits&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> <span style=\"color: #006699; font-weight: bold;\">namespace<\/span> std;\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\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> getPrimaryTypeCategory(){\r\n\r\n  cout <span style=\"color: #555555;\">&lt;&lt;<\/span> boolalpha <span style=\"color: #555555;\">&lt;&lt;<\/span> endl;\r\n\r\n  cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"is_void&lt;T&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> is_void<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&lt;&lt;<\/span> endl;\r\n  cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"is_integral&lt;T&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> is_integral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&lt;&lt;<\/span> endl;\r\n  cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"is_floating_point&lt;T&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> is_floating_point<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&lt;&lt;<\/span> endl;\r\n  cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"is_array&lt;T&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> is_array<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&lt;&lt;<\/span> endl;\r\n  cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"is_pointer&lt;T&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> is_pointer<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&lt;&lt;<\/span> endl;\r\n  cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"is_null_pointer&lt;T&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> is_null_pointer<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&lt;&lt;<\/span> endl;\r\n  cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"is_member_object_pointer&lt;T&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> is_member_object_pointer<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&lt;&lt;<\/span> endl;\r\n  cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"is_member_function_pointer&lt;T&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> is_member_function_pointer<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&lt;&lt;<\/span> endl;\r\n  cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"is_enum&lt;T&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> is_enum<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&lt;&lt;<\/span> endl;\r\n  cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"is_union&lt;T&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> is_union<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&lt;&lt;<\/span> endl;\r\n  cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"is_class&lt;T&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> is_class<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&lt;&lt;<\/span> endl;\r\n  cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"is_function&lt;T&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> is_function<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&lt;&lt;<\/span> endl;\r\n  cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"is_lvalue_reference&lt;T&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> is_lvalue_reference<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&lt;&lt;<\/span> endl;\r\n  cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"is_rvalue_reference&lt;T&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> is_rvalue_reference<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&lt;&lt;<\/span> endl;\r\n\r\n  cout <span style=\"color: #555555;\">&lt;&lt;<\/span> endl;\r\n\r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> main(){\r\n    \r\n    getPrimaryTypeCategory<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">void<\/span><span style=\"color: #555555;\">&gt;<\/span>();              <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n    getPrimaryTypeCategory<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">short<\/span><span style=\"color: #555555;\">&gt;<\/span>();             <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n    getPrimaryTypeCategory<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">double<\/span><span style=\"color: #555555;\">&gt;<\/span>();\r\n    getPrimaryTypeCategory<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span> []<span style=\"color: #555555;\">&gt;<\/span>();\r\n    getPrimaryTypeCategory<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">*&gt;<\/span>();\r\n    getPrimaryTypeCategory<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">std::nullptr_t<\/span><span style=\"color: #555555;\">&gt;<\/span>();\r\n    <span style=\"color: #006699; font-weight: bold;\">struct<\/span> A{\r\n        <span style=\"color: #007788; font-weight: bold;\">int<\/span> a;\r\n        <span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">f<\/span>(<span style=\"color: #007788; font-weight: bold;\">double<\/span>){<span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #ff6600;\">2011<\/span>;}\r\n    };\r\n    getPrimaryTypeCategory<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span> A<span style=\"color: #555555;\">::*&gt;<\/span>();\r\n    getPrimaryTypeCategory<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span> (A<span style=\"color: #555555;\">::*<\/span>)(<span style=\"color: #007788; font-weight: bold;\">double<\/span>)<span style=\"color: #555555;\">&gt;<\/span>();\r\n    <span style=\"color: #006699; font-weight: bold;\">enum<\/span> E{\r\n        e<span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">1<\/span>,\r\n    };\r\n    getPrimaryTypeCategory<span style=\"color: #555555;\">&lt;<\/span>E<span style=\"color: #555555;\">&gt;<\/span>();\r\n    <span style=\"color: #006699; font-weight: bold;\">union<\/span> U{\r\n      <span style=\"color: #007788; font-weight: bold;\">int<\/span> u;\r\n    };\r\n    getPrimaryTypeCategory<span style=\"color: #555555;\">&lt;<\/span>U<span style=\"color: #555555;\">&gt;<\/span>();\r\n    getPrimaryTypeCategory<span style=\"color: #555555;\">&lt;<\/span>string<span style=\"color: #555555;\">&gt;<\/span>();\r\n    getPrimaryTypeCategory<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #555555;\">*<\/span> (<span style=\"color: #007788; font-weight: bold;\">double<\/span>)<span style=\"color: #555555;\">&gt;<\/span>();\r\n    getPrimaryTypeCategory<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&amp;&gt;<\/span>();              <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)         <\/span>\r\n    getPrimaryTypeCategory<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&amp;&amp;&gt;<\/span>();             <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n    \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>I don&#8217;t want to bore you to death. Therefore, there is only the output of the line (1).<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5535\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/traitsPrimaryFixed1.png\" alt=\"traitsPrimaryFixed1\" width=\"450\" height=\"586\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/traitsPrimaryFixed1.png 529w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/traitsPrimaryFixed1-230x300.png 230w\" sizes=\"auto, (max-width: 450px) 100vw, 450px\" \/><\/p>\n<p>And here is the output of line (2).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5536\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/traitsPrimaryFixed2.png\" alt=\"traitsPrimaryFixed2\" width=\"450\" height=\"600\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/traitsPrimaryFixed2.png 529w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/traitsPrimaryFixed2-225x300.png 225w\" sizes=\"auto, (max-width: 450px) 100vw, 450px\" \/><\/p>\n<p>&nbsp;<\/p>\n<h3>Tag Dispatching<\/h3>\n<p>Tag dispatching enables it to choose a function based on the properties of its types. The decision takes place at compile time, and traits which I explained in the last paragraph are used.&nbsp;<\/p>\n<p>A typical example of tag dispatching is the <span style=\"font-family: 'courier new', courier;\"><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/iterator\/advance\">std::advance<\/a>&nbsp;<\/span>algorithm from the Standard Template Library. <span style=\"font-family: 'courier new', courier;\">std::advance(it, n)<\/span> increments the iterator<span style=\"font-family: 'courier new', courier;\"> it<\/span> by <span style=\"font-family: 'courier new', courier;\">n<\/span> elements. The program shows you the key idea.<\/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;\">\/\/ advanceTagDispatch.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iterator&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;forward_list&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;list&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;vector&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> InputIterator, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> Distance<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> advance_impl(InputIterator<span style=\"color: #555555;\">&amp;<\/span> i, Distance n, std<span style=\"color: #555555;\">::<\/span>input_iterator_tag) {\r\n\tstd<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"InputIterator used\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl; \r\n    <span style=\"color: #006699; font-weight: bold;\">while<\/span> (n<span style=\"color: #555555;\">--<\/span>) <span style=\"color: #555555;\">++<\/span>i;\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> BidirectionalIterator, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> Distance<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> advance_impl(BidirectionalIterator<span style=\"color: #555555;\">&amp;<\/span> i, Distance n, std<span style=\"color: #555555;\">::<\/span>bidirectional_iterator_tag) {\r\n\tstd<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"BidirectionalIterator used\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span> (n <span style=\"color: #555555;\">&gt;=<\/span> <span style=\"color: #ff6600;\">0<\/span>) \r\n        <span style=\"color: #006699; font-weight: bold;\">while<\/span> (n<span style=\"color: #555555;\">--<\/span>) <span style=\"color: #555555;\">++<\/span>i;\r\n    <span style=\"color: #006699; font-weight: bold;\">else<\/span> \r\n        <span style=\"color: #006699; font-weight: bold;\">while<\/span> (n<span style=\"color: #555555;\">++<\/span>) <span style=\"color: #555555;\">--<\/span>i;\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> RandomAccessIterator, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> Distance<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> advance_impl(RandomAccessIterator<span style=\"color: #555555;\">&amp;<\/span> i, Distance n, std<span style=\"color: #555555;\">::<\/span>random_access_iterator_tag) {\r\n\tstd<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"RandomAccessIterator used\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    i <span style=\"color: #555555;\">+=<\/span> n;\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> InputIterator, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> Distance<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> advance_(InputIterator<span style=\"color: #555555;\">&amp;<\/span> i, Distance n) {\r\n    <span style=\"color: #006699; font-weight: bold;\">typename<\/span> std<span style=\"color: #555555;\">::<\/span>iterator_traits<span style=\"color: #555555;\">&lt;<\/span>InputIterator<span style=\"color: #555555;\">&gt;::<\/span>iterator_category category;    <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n    advance_impl(i, n, category);                                                <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\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>vector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> myVec{<span style=\"color: #ff6600;\">0<\/span>, <span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">4<\/span>, <span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #ff6600;\">6<\/span>, <span style=\"color: #ff6600;\">7<\/span>, <span style=\"color: #ff6600;\">8<\/span>, <span style=\"color: #ff6600;\">9<\/span>};\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> myVecIt <span style=\"color: #555555;\">=<\/span> myVec.begin();                                                <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;\">\"*myVecIt: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>myVecIt <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    advance_(myVecIt, <span style=\"color: #ff6600;\">5<\/span>);\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"*myVecIt: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>myVecIt <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    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;\">0<\/span>, <span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">4<\/span>, <span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #ff6600;\">6<\/span>, <span style=\"color: #ff6600;\">7<\/span>, <span style=\"color: #ff6600;\">8<\/span>, <span style=\"color: #ff6600;\">9<\/span>};\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> myListIt <span style=\"color: #555555;\">=<\/span> myList.begin();                                              <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"*myListIt: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>myListIt <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    advance_(myListIt, <span style=\"color: #ff6600;\">5<\/span>);\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"*myListIt: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>myListIt <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    std<span style=\"color: #555555;\">::<\/span>forward_list<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> myForwardList{<span style=\"color: #ff6600;\">0<\/span>, <span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">4<\/span>, <span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #ff6600;\">6<\/span>, <span style=\"color: #ff6600;\">7<\/span>, <span style=\"color: #ff6600;\">8<\/span>, <span style=\"color: #ff6600;\">9<\/span>};\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> myForwardListIt <span style=\"color: #555555;\">=<\/span> myForwardList.begin();                                <span style=\"color: #0099ff; font-style: italic;\">\/\/ (5)<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"*myForwardListIt: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>myForwardListIt <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    advance_(myForwardListIt, <span style=\"color: #ff6600;\">5<\/span>);\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"*myForwardListIt: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>myForwardListIt <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>The expression&nbsp;<span style=\"font-family: 'courier new', courier;\">std::iterator_traits::iterator_category category&nbsp;<\/span>determines the iterator category at compile time. Based on the iterator category, the most specific variable of the function&nbsp;<span style=\"font-family: 'courier new', courier;\">advance_impl(i, n, category)&nbsp;<\/span>is used in line (2). Each container returns an iterator of the iterator category corresponding to its structure. Therefore, line (3) gives a random access iterator, line (4) gives a bidirectional iterator, and line (5) gives a forward iterator which is also an input iterator.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5537\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/advanceTagDispatch.png\" alt=\"advanceTagDispatch\" width=\"400\" height=\"335\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/advanceTagDispatch.png 678w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/advanceTagDispatch-300x251.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/>This distinction makes a lot of sense from the performance point of view because a random access iterator can be faster incremented than a bidirectional iterator, and a bidirectional iterator can be faster incremented than an input iterator. From the user&#8217;s perspective, you invoke<span style=\"font-family: 'courier new', courier;\"> std::advance(it, 5<\/span>) and get the fastest version your container satisfies.<\/p>\n<p>This was quite verbose. I have not so much to add to the two remaining rules.<\/p>\n<h2><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-not\" style=\"color: #268bd2; text-decoration: none;\">T.25: Avoid complimen<\/a><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-not\" style=\"color: #268bd2; text-decoration: none;\">tary constraints<\/a><\/h2>\n<p>The example from the guidelines shows complementary constraints.<\/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    requires <span style=\"color: #555555;\">!<\/span>C<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #0099ff; font-style: italic;\">\/\/ bad <\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> f(); \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\n    requires C<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span> \r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> f();\r\n<\/pre>\n<\/div>\n<p><br class=\"no-highlight\" style=\"font-family: 'Roboto Mono', monospace; padding: 0.5em; font-size: 16px; background-color: transparent; display: inline-block; min-width: 50em; color: black;\" \/><\/p>\n<p>Avoid it. Make an unconstrained template and a constrained template&nbsp;instead.<\/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><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>   <span style=\"color: #0099ff; font-style: italic;\">\/\/ general template<\/span>\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> f();\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;\">\/\/ specialization by concept<\/span>\r\n    requires C<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> f();\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>You can even set the unconstrained version to <span style=\"font-family: 'courier new', courier;\">delete<\/span> so that the constrained versions are only used.<\/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: #007788; font-weight: bold;\">void<\/span> f() <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">delete<\/span>;\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<h2><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-use\" style=\"color: #268bd2; text-decoration: none;\">T.26: Prefer to define concepts in terms of use patterns rather than simple syntax<\/a><\/h2>\n<p>The title for this guideline is quite vague, but the example is self-explanatory.<\/p>\n<p>Instead of using the concepts <span style=\"font-family: courier new, courier;\">has_equal<\/span> and <span style=\"font-family: courier new, courier;\">has_not_equal<\/span> to define the concept <span style=\"font-family: courier new, courier;\">Equality <\/span><\/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> concept Equality <span style=\"color: #555555;\">=<\/span> has_equal<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #555555;\">&amp;&amp;<\/span> has_not_equal<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span>;\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>use the usage pattern. This is more readable than the previous version:<\/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> concept Equality <span style=\"color: #555555;\">=<\/span> requires(T a, T b) {\r\n    <span style=\"color: #007788; font-weight: bold;\">bool<\/span> <span style=\"color: #555555;\">==<\/span> { a <span style=\"color: #555555;\">==<\/span> b }\r\n    <span style=\"color: #007788; font-weight: bold;\">bool<\/span> <span style=\"color: #555555;\">==<\/span> { a <span style=\"color: #555555;\">!=<\/span> b }\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ axiom { !(a == b) == (a != b) }<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ axiom { a = b; =&gt; a == b }  \/\/ =&gt; means \"implies\"<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p><span style=\"font-family: 'courier new', courier;\">In this case the concept&nbsp;<\/span><span style=\"font-family: 'courier new', courier;\">Equality<\/span> requires you to apply <span style=\"font-family: courier new, courier;\">==<\/span> and <span style=\"font-family: courier new, courier;\">!=<\/span> to the arguments, and both operations return <span style=\"font-family: courier new, courier;\">bool.<\/span><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>Here is a part of the opening from the C++ core guidelines to template interfaces: &#8220;&#8230;the interface to a template is a critical concept &#8211; a contract between a user and an implementer &#8211; and should be carefully designed.&#8221;. You see, the<a href=\"http:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-rules-for-template-interfaces\"> next post<\/a> is critical.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Let me continue with the rules for defining concepts in the guidelines. The first of the three remaining rules in this post is quite sophisticated.<\/p>\n","protected":false},"author":21,"featured_media":5534,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[415],"class_list":["post-5538","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c","tag-concepts"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5538","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=5538"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5538\/revisions"}],"predecessor-version":[{"id":6808,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5538\/revisions\/6808"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5534"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5538"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5538"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5538"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}