{"id":5578,"date":"2018-12-09T17:49:47","date_gmt":"2018-12-09T17:49:47","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-specialisation-of-templates\/"},"modified":"2018-12-09T17:49:47","modified_gmt":"2018-12-09T17:49:47","slug":"c-core-guidelines-specialisation-of-templates","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-specialisation-of-templates\/","title":{"rendered":"C++ Core Guidelines: Ordering of User-Defined Types"},"content":{"rendered":"<p>My post for today is just loosely coupled to the rules of the C++ core guidelines because they do provide not much content. Inspired by the guidelines, today&#8217;s post concerns a generic <span style=\"font-family: 'courier new', courier;\">isSmaller <\/span>function.<\/p>\n<p><!--more--><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5572\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/hammer-802301_1280.jpg\" alt=\"hammer 802301 1280\" width=\"500\" height=\"375\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/hammer-802301_1280.jpg 1280w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/hammer-802301_1280-300x225.jpg 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/hammer-802301_1280-1024x768.jpg 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/hammer-802301_1280-768x576.jpg 768w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/>&nbsp;<\/p>\n<p>Here are the rules for today. They are about the specialization of templates.<\/p>\n<ul>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-specialization\">T.64: Use specialization to provide alternative implementations of class templates<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-tag-dispatch\">T.65: Use tag dispatch to provide alternative implementations of functions<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-specialization2\">T.67: Use specialization to provide alternative implementations for irregular types<\/a><\/li>\n<\/ul>\n<p>The specialization of function templates is also one of my topics for today.<\/p>\n<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Comparing_two_Accounts_The_First\"><\/span>Comparing two Accounts: The First<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Let me start simply. I have a class <span style=\"font-family: courier new, courier;\">Account<\/span>. I want to know if an account is smaller than another account. Smaller means, in this case, that the balance is lower.<\/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;\">\/\/ isSmaller.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Account<\/span>{\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n  Account() <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">default<\/span>;\r\n  Account(<span style=\"color: #007788; font-weight: bold;\">double<\/span> b)<span style=\"color: #555555;\">:<\/span> balance(b){}\r\n  <span style=\"color: #007788; font-weight: bold;\">double<\/span> getBalance() <span style=\"color: #006699; font-weight: bold;\">const<\/span> {\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> balance;\r\n  }\r\n<span style=\"color: #9999ff;\">private:<\/span>\r\n  <span style=\"color: #007788; font-weight: bold;\">double<\/span> balance{<span style=\"color: #ff6600;\">0.0<\/span>};\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;\">\/\/ (1)<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">bool<\/span> isSmaller(T fir, T sec){\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> fir <span style=\"color: #555555;\">&lt;<\/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>boolalpha <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;\">double<\/span> firDoub{};\r\n    <span style=\"color: #007788; font-weight: bold;\">double<\/span> secDoub{<span style=\"color: #ff6600;\">2014.0<\/span>};\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"isSmaller(firDoub, secDoub): \"<\/span> \r\n              <span style=\"color: #555555;\">&lt;&lt;<\/span> isSmaller(firDoub, secDoub) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n    Account firAcc{};\r\n    Account secAcc{<span style=\"color: #ff6600;\">2014.0<\/span>};\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"isSmaller(firAcc, secAcc): \"<\/span> \r\n              <span style=\"color: #555555;\">&lt;&lt;<\/span> isSmaller(firAcc, secAcc) <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>To simplify my job, I wrote a generic <span style=\"font-family: courier new, courier;\">isSmaller<\/span> function (1) for comparing two values. As you presumably expected, I can not compare accounts because its<span style=\"font-family: courier new, courier;\"> operator&lt;<\/span> is not overloaded.<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5573\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/isSmaller.png\" alt=\"isSmaller\" width=\"600\" height=\"142\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/isSmaller.png 1541w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/isSmaller-300x71.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/isSmaller-1024x243.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/isSmaller-768x182.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/isSmaller-1536x364.png 1536w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>Before I variously solve this issue, I want to make a short detour to<span style=\"font-family: courier new, courier;\"> SemiRegular<\/span> and <span style=\"font-family: courier new, courier;\">Regular<\/span> types. This is for one reason the original definition of Regular from <a href=\"https:\/\/en.wikipedia.org\/wiki\/Alexander_Stepanov\">Alexander Stepanov<\/a> and the definition as a concept in C++20 differs in one critical point: ordering.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"SemiRegular_and_Regular_Types\"><\/span><span style=\"font-family: courier new, courier;\">SemiRegular<\/span> and <span style=\"font-family: courier new, courier;\">Regular<\/span> Types<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Rule <a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-specialization2\">T.67: Use specialization to provide alternative implementations for irregular types<\/a> talks about irregular types. The informal term irregular types stand for either <span style=\"font-family: courier new, courier;\">SemiRegular<\/span> or <span style=\"font-family: courier new, courier;\">Regular<\/span>. To remind you. Here is the definition of <span style=\"font-family: courier new, courier;\">SemiRegular<\/span> and <span style=\"font-family: courier new, courier;\">Regular<\/span> types.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Regular\"><\/span><span style=\"font-family: courier new, courier;\">Regular<\/span><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<ul>\n<li><span style=\"font-family: courier new, courier;\">DefaultConstructible<\/span><\/li>\n<li><span style=\"font-family: courier new, courier;\">CopyConstructible, CopyAssignable<\/span><\/li>\n<li><span style=\"font-family: courier new, courier;\">MoveConstructible, MoveAssignable<\/span><\/li>\n<li><span style=\"font-family: courier new, courier;\">Destructible<\/span><\/li>\n<li><span style=\"font-family: courier new, courier;\">Swappable<\/span><\/li>\n<li><span style=\"font-family: courier new, courier;\">EqualityComparable<\/span><\/li>\n<\/ul>\n<h3><span class=\"ez-toc-section\" id=\"SemiRegular\"><\/span><span style=\"font-family: courier new, courier;\">SemiRegular<\/span><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<ul>\n<li><span style=\"font-family: courier new, courier;\">SemiRegular &#8211; EqualityComparable<\/span><\/li>\n<\/ul>\n<p>If you want more details about Regular and SemiRegular, read my post&nbsp; <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-regular-and-semiregular-typs\">C++ Core Guidelines: Regular and SemiRegular Types<\/a>. The account is a <span style=\"font-family: courier new, courier;\">SemiRegular<\/span> but not a <span style=\"font-family: courier new, courier;\">Regular<\/span> type.<\/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;\">\/\/ accountSemiRegular.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;experimental\/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;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Account<\/span>{\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n  Account() <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">default<\/span>;\r\n  Account(<span style=\"color: #007788; font-weight: bold;\">double<\/span> b)<span style=\"color: #555555;\">:<\/span> balance(b){}\r\n  <span style=\"color: #007788; font-weight: bold;\">double<\/span> getAccount() <span style=\"color: #006699; font-weight: bold;\">const<\/span> {\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> balance;\r\n  }\r\n<span style=\"color: #9999ff;\">private:<\/span>\r\n  <span style=\"color: #007788; font-weight: bold;\">double<\/span> balance{<span style=\"color: #ff6600;\">0.0<\/span>};\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>\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> <span style=\"color: #007788; font-weight: bold;\">equal_comparable_t<\/span> <span style=\"color: #555555;\">=<\/span> decltype(std<span style=\"color: #555555;\">::<\/span>declval<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&amp;&gt;<\/span>() <span style=\"color: #555555;\">==<\/span> std<span style=\"color: #555555;\">::<\/span>declval<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&amp;&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\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> isEqualityComparable<span style=\"color: #555555;\">:<\/span> \r\n       std<span style=\"color: #555555;\">::<\/span>experimental<span style=\"color: #555555;\">::<\/span>is_detected<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">equal_comparable_t<\/span>, T<span style=\"color: #555555;\">&gt;<\/span>\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>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> isSemiRegular<span style=\"color: #555555;\">:<\/span> std<span style=\"color: #555555;\">::<\/span>integral_constant<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">bool<\/span>,\r\n                                      std<span style=\"color: #555555;\">::<\/span>is_default_constructible<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&amp;&amp;<\/span>\r\n                                      std<span style=\"color: #555555;\">::<\/span>is_copy_constructible<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&amp;&amp;<\/span>\r\n                                      std<span style=\"color: #555555;\">::<\/span>is_copy_assignable<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&amp;&amp;<\/span>\r\n                                      std<span style=\"color: #555555;\">::<\/span>is_move_constructible<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&amp;&amp;<\/span>\r\n                                      std<span style=\"color: #555555;\">::<\/span>is_move_assignable<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&amp;&amp;<\/span>\r\n                                      std<span style=\"color: #555555;\">::<\/span>is_destructible<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&amp;&amp;<\/span>\r\n                                      std<span style=\"color: #555555;\">::<\/span>is_swappable<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&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\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> isRegular<span style=\"color: #555555;\">:<\/span> std<span style=\"color: #555555;\">::<\/span>integral_constant<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">bool<\/span>, \r\n                                         isSemiRegular<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&amp;&amp;<\/span>\r\n                                         isEqualityComparable<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&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>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> <span style=\"color: #cc3300;\">\"isSemiRegular&lt;Account&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> isSemiRegular<span style=\"color: #555555;\">&lt;<\/span>Account<span style=\"color: #555555;\">&gt;::<\/span>value <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;\">\"isRegular&lt;Account&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> isRegular<span style=\"color: #555555;\">&lt;<\/span>Account<span style=\"color: #555555;\">&gt;::<\/span>value <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 output of the program shows it.<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5574\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/accountSemiRegular.png\" alt=\"accountSemiRegular\" width=\"400\" height=\"186\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/accountSemiRegular.png 723w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/accountSemiRegular-300x140.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>For the details of the program, read my already mentioned post: <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-regular-and-semiregular-typs\">C++ Core Guidelines: Regular and SemiRegular Types<\/a>.<\/p>\n<p>By adding the<span style=\"font-family: courier new, courier;\"> operator ==<\/span> to <span style=\"font-family: courier new, courier;\">Account<\/span>, <span style=\"font-family: courier new, courier;\">Account<\/span> becomes <span style=\"font-family: courier new, courier;\">Regular<\/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: #0099ff; font-style: italic;\">\/\/ accountRegular.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Account<\/span>{\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n    Account() <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">default<\/span>;\r\n    Account(<span style=\"color: #007788; font-weight: bold;\">double<\/span> b)<span style=\"color: #555555;\">:<\/span> balance(b){}\r\n    <span style=\"color: #006699; font-weight: bold;\">friend<\/span> <span style=\"color: #007788; font-weight: bold;\">bool<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span> <span style=\"color: #555555;\">==<\/span> (Account <span style=\"color: #006699; font-weight: bold;\">const<\/span><span style=\"color: #555555;\">&amp;<\/span> fir, Account <span style=\"color: #006699; font-weight: bold;\">const<\/span><span style=\"color: #555555;\">&amp;<\/span> sec) {   <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> fir.getBalance() <span style=\"color: #555555;\">==<\/span> sec.getBalance();\r\n    }\r\n    <span style=\"color: #007788; font-weight: bold;\">double<\/span> getBalance() <span style=\"color: #006699; font-weight: bold;\">const<\/span> {\r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> balance;\r\n    }\r\n<span style=\"color: #9999ff;\">private:<\/span>\r\n    <span style=\"color: #007788; font-weight: bold;\">double<\/span> balance{<span style=\"color: #ff6600;\">0.0<\/span>};\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>\r\n<span style=\"color: #007788; font-weight: bold;\">bool<\/span> isSmaller(T fir, T sec){\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> fir <span style=\"color: #555555;\">&lt;<\/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>boolalpha <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;\">double<\/span> firDou{};\r\n    <span style=\"color: #007788; font-weight: bold;\">double<\/span> secDou{<span style=\"color: #ff6600;\">2014.0<\/span>};\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"isSmaller(firDou, secDou): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> isSmaller(firDou, secDou) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n    Account firAcc{};\r\n    Account secAcc{<span style=\"color: #ff6600;\">2014.0<\/span>};\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"isSmaller(firAcc, secAcc): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> isSmaller(firAcc, secAcc) <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>But <span style=\"font-family: courier new, courier;\">Account<\/span> is still not comparable.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5575\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/accountRegular.png\" alt=\"accountRegular\" width=\"600\" height=\"134\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/accountRegular.png 1621w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/accountRegular-300x67.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/accountRegular-1024x229.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/accountRegular-768x172.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/accountRegular-1536x344.png 1536w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>This is the crucial difference between Regular types defined by Alexander Stepanov and the concept of Regular, which we get with C++20. Due to Alexander Stepanov, a Regular type should support a&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Total_order\"> total ordering<\/a>.<\/p>\n<p>Now, I have come back to my original plan.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Comparing_Two_Accounts_The_Second\"><\/span>Comparing Two Accounts: The Second<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The key idea for my variations is that instances of <span style=\"font-family: courier new, courier;\">Account<\/span> should support the generic <span style=\"font-family: courier new, courier;\">isSmaller<\/span> function.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Overloading_operator\"><\/span>Overloading <span style=\"font-family: courier new, courier;\">operator &lt;<\/span><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Overloading <span style=\"font-family: courier new, courier;\">operator &lt;<\/span> is probably the most obvious way. Even the error message to the program<span style=\"font-family: courier new, courier;\"> isSmaller.cpp<\/span> showed it.<\/p>\n<div style=\"background: #f0f3f3 none repeat scroll 0% 0%; overflow: auto; width: auto; border-width: 0.1em 0.1em 0.1em 0.8em;\">\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ accountIsSmaller1.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Account<\/span>{\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n    Account() <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">default<\/span>;\r\n    Account(<span style=\"color: #007788; font-weight: bold;\">double<\/span> b)<span style=\"color: #555555;\">:<\/span> balance(b){}\r\n    <span style=\"color: #006699; font-weight: bold;\">friend<\/span> <span style=\"color: #007788; font-weight: bold;\">bool<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span> <span style=\"color: #555555;\">==<\/span> (Account <span style=\"color: #006699; font-weight: bold;\">const<\/span><span style=\"color: #555555;\">&amp;<\/span> fir, Account <span style=\"color: #006699; font-weight: bold;\">const<\/span><span style=\"color: #555555;\">&amp;<\/span> sec) { \r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> fir.getBalance() <span style=\"color: #555555;\">==<\/span> sec.getBalance();\r\n    }\r\n    <span style=\"color: #006699; font-weight: bold;\">friend<\/span> <span style=\"color: #007788; font-weight: bold;\">bool<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span> <span style=\"color: #555555;\">&lt;<\/span> (Account <span style=\"color: #006699; font-weight: bold;\">const<\/span><span style=\"color: #555555;\">&amp;<\/span> fir, Account <span style=\"color: #006699; font-weight: bold;\">const<\/span><span style=\"color: #555555;\">&amp;<\/span> sec) { \r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> fir.getBalance() <span style=\"color: #555555;\">&lt;<\/span> sec.getBalance();\r\n    }\r\n    <span style=\"color: #007788; font-weight: bold;\">double<\/span> getBalance() <span style=\"color: #006699; font-weight: bold;\">const<\/span> {\r\n      <span style=\"color: #006699; font-weight: bold;\">return<\/span> balance;\r\n    }\r\n<span style=\"color: #9999ff;\">private:<\/span>\r\n    <span style=\"color: #007788; font-weight: bold;\">double<\/span> balance{<span style=\"color: #ff6600;\">0.0<\/span>};\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>\r\n<span style=\"color: #007788; font-weight: bold;\">bool<\/span> isSmaller(T fir, T sec){\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> fir <span style=\"color: #555555;\">&lt;<\/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>boolalpha <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;\">double<\/span> firDou{};\r\n    <span style=\"color: #007788; font-weight: bold;\">double<\/span> secDou{<span style=\"color: #ff6600;\">2014.0<\/span>};\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"isSmaller(firDou, secDou): \"<\/span> \r\n              <span style=\"color: #555555;\">&lt;&lt;<\/span> isSmaller(firDou, secDou) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n    Account firAcc{};\r\n    Account secAcc{<span style=\"color: #ff6600;\">2014.0<\/span>};\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"isSmaller(firAcc, secAcc): \"<\/span> \r\n              <span style=\"color: #555555;\">&lt;&lt;<\/span> isSmaller(firAcc, secAcc) <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 output of this and the next program is the same; therefore, I skip it.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Full_Specialisation_of_isSmaller\"><\/span>Full Specialisation of <span style=\"font-family: courier new, courier;\">isSmaller<\/span><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>If you can not change the definition of <span style=\"font-family: courier new, courier;\">Account<\/span>, you can at least entirely specialize <span style=\"font-family: Courier New, Courier, monospace;\">isSmaller <\/span>for <span style=\"font-family: Courier New, Courier, monospace;\">Account<\/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: #0099ff; font-style: italic;\">\/\/ accountIsSmaller2.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Account<\/span>{\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n    Account() <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">default<\/span>;\r\n    Account(<span style=\"color: #007788; font-weight: bold;\">double<\/span> b)<span style=\"color: #555555;\">:<\/span> balance(b){}\r\n    <span style=\"color: #006699; font-weight: bold;\">friend<\/span> <span style=\"color: #007788; font-weight: bold;\">bool<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span> <span style=\"color: #555555;\">==<\/span> (Account <span style=\"color: #006699; font-weight: bold;\">const<\/span><span style=\"color: #555555;\">&amp;<\/span> fir, Account <span style=\"color: #006699; font-weight: bold;\">const<\/span><span style=\"color: #555555;\">&amp;<\/span> sec) { \r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> fir.getBalance() <span style=\"color: #555555;\">==<\/span> sec.getBalance();\r\n    }\r\n    <span style=\"color: #007788; font-weight: bold;\">double<\/span> getBalance() <span style=\"color: #006699; font-weight: bold;\">const<\/span> {\r\n      <span style=\"color: #006699; font-weight: bold;\">return<\/span> balance;\r\n    }\r\n<span style=\"color: #9999ff;\">private:<\/span>\r\n    <span style=\"color: #007788; font-weight: bold;\">double<\/span> balance{<span style=\"color: #ff6600;\">0.0<\/span>};\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>\r\n<span style=\"color: #007788; font-weight: bold;\">bool<\/span> isSmaller(T fir, T sec){\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> fir <span style=\"color: #555555;\">&lt;<\/span> sec;\r\n}\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">bool<\/span> isSmaller<span style=\"color: #555555;\">&lt;<\/span>Account<span style=\"color: #555555;\">&gt;<\/span>(Account fir, Account sec){\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> fir.getBalance() <span style=\"color: #555555;\">&lt;<\/span> sec.getBalance();\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>boolalpha <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;\">double<\/span> firDou{};\r\n    <span style=\"color: #007788; font-weight: bold;\">double<\/span> secDou{<span style=\"color: #ff6600;\">2014.0<\/span>};\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"isSmaller(firDou, secDou): \"<\/span> \r\n              <span style=\"color: #555555;\">&lt;&lt;<\/span> isSmaller(firDou, secDou) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n    Account firAcc{};\r\n    Account secAcc{<span style=\"color: #ff6600;\">2014.0<\/span>};\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"isSmaller(firAcc, secAcc): \"<\/span> \r\n              <span style=\"color: #555555;\">&lt;&lt;<\/span> isSmaller(firAcc, secAcc) <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>By the way, a non-generic function&nbsp;<span style=\"font-family: courier new, courier;\">bool isSmaller(Account fir, Account sec<\/span>) would also do the job.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Extend_isSmaller_with_a_Binary_Predicate\"><\/span>Extend <span style=\"font-family: courier new, courier;\">isSmaller<\/span> with a Binary Predicate<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>There is another way to extend <span style=\"font-family: courier new, courier;\">isSmaller<\/span>. I spend the generic function an additional type parameter <span style=\"font-family: courier new, courier;\">Pred<\/span>, which should hold the binary predicate. This pattern is often used in the standard template library.<\/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;\">\/\/ accountIsSmaller3.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;functional&gt;<\/span>\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;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Account<\/span>{\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n    Account() <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">default<\/span>;\r\n    Account(<span style=\"color: #007788; font-weight: bold;\">double<\/span> b)<span style=\"color: #555555;\">:<\/span> balance(b){}\r\n    <span style=\"color: #006699; font-weight: bold;\">friend<\/span> <span style=\"color: #007788; font-weight: bold;\">bool<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span> <span style=\"color: #555555;\">==<\/span> (Account <span style=\"color: #006699; font-weight: bold;\">const<\/span><span style=\"color: #555555;\">&amp;<\/span> fir, Account <span style=\"color: #006699; font-weight: bold;\">const<\/span><span style=\"color: #555555;\">&amp;<\/span> sec) { \r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> fir.getBalance() <span style=\"color: #555555;\">==<\/span> sec.getBalance();\r\n    }\r\n    <span style=\"color: #007788; font-weight: bold;\">double<\/span> getBalance() <span style=\"color: #006699; font-weight: bold;\">const<\/span> {\r\n      <span style=\"color: #006699; font-weight: bold;\">return<\/span> balance;\r\n    }\r\n<span style=\"color: #9999ff;\">private:<\/span>\r\n    <span style=\"color: #007788; font-weight: bold;\">double<\/span> balance{<span style=\"color: #ff6600;\">0.0<\/span>};\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: #006699; font-weight: bold;\">typename<\/span> Pred <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>less<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #555555;\">&gt;<\/span>    <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">bool<\/span> isSmaller(T fir, T sec, Pred pred <span style=\"color: #555555;\">=<\/span> Pred() ){      <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n  <span style=\"color: #006699; font-weight: bold;\">return<\/span> pred(fir, sec);                                <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/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>boolalpha <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;\">double<\/span> firDou{};\r\n    <span style=\"color: #007788; font-weight: bold;\">double<\/span> secDou{<span style=\"color: #ff6600;\">2014.0<\/span>};\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"isSmaller(firDou, secDou): \"<\/span> \r\n              <span style=\"color: #555555;\">&lt;&lt;<\/span> isSmaller(firDou, secDou) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n    Account firAcc{};\r\n    Account secAcc{<span style=\"color: #ff6600;\">2014.0<\/span>};\r\n    \r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> res <span style=\"color: #555555;\">=<\/span> isSmaller(firAcc, secAcc,                               <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n                         [](<span style=\"color: #006699; font-weight: bold;\">const<\/span> Account<span style=\"color: #555555;\">&amp;<\/span> fir, <span style=\"color: #006699; font-weight: bold;\">const<\/span> Account<span style=\"color: #555555;\">&amp;<\/span> sec){\r\n                             <span style=\"color: #006699; font-weight: bold;\">return<\/span> fir.getBalance() <span style=\"color: #555555;\">&lt;<\/span> sec.getBalance(); \r\n                         }\r\n    );\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"isSmaller(firAcc, secAcc): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span>  res <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>string firStr <span style=\"color: #555555;\">=<\/span> <span style=\"color: #cc3300;\">\"AAA\"<\/span>;\r\n    std<span style=\"color: #555555;\">::<\/span>string secStr <span style=\"color: #555555;\">=<\/span> <span style=\"color: #cc3300;\">\"BB\"<\/span>;\r\n     \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"isSmaller(firStr, secStr): \"<\/span> \r\n              <span style=\"color: #555555;\">&lt;&lt;<\/span>  isSmaller(firStr, secStr) <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;\">auto<\/span> res2 <span style=\"color: #555555;\">=<\/span> isSmaller(firStr, secStr,                             <span style=\"color: #0099ff; font-style: italic;\">\/\/ (5)<\/span>\r\n                           [](<span style=\"color: #006699; font-weight: bold;\">const<\/span> std<span style=\"color: #555555;\">::<\/span>string<span style=\"color: #555555;\">&amp;<\/span> fir, <span style=\"color: #006699; font-weight: bold;\">const<\/span> std<span style=\"color: #555555;\">::<\/span>string<span style=\"color: #555555;\">&amp;<\/span> sec){\r\n                               <span style=\"color: #006699; font-weight: bold;\">return<\/span> fir.length() <span style=\"color: #555555;\">&lt;<\/span> sec.length(); \r\n                           }\r\n    );\r\n     \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"isSmaller(firStr, secStr): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span>  res2 <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 generic function has <span style=\"font-family: courier new, courier;\">std::less&lt;T<\/span>&gt; as the default ordering (1). The binary predicate <span style=\"font-family: courier new, courier;\">Pred<\/span> is instantiated in line (2) and used in line (3). If you don&#8217;t specify the binary predicate, <span style=\"font-family: courier new, courier;\">std::less<\/span> is used. Additionally, you can provide your binary predicates, such as in line (4) or line (5). A lambda function is an ideal fit for this job.<\/p>\n<p>Finally, here is the output of the program:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5576\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/accountIsSmaller3.png\" alt=\"accountIsSmaller3\" width=\"400\" height=\"226\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/accountIsSmaller3.png 726w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/accountIsSmaller3-300x169.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>What are the differences between these three techniques?<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Comparing_two_Accounts_The_Third\"><\/span>Comparing two Accounts: The Third<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5577\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/ComparisonNew.png\" alt=\"ComparisonNew\" width=\"600\" height=\"222\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/ComparisonNew.png 735w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/12\/ComparisonNew-300x111.png 300w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>The full specialization is not a general solution because it only works for the function <span style=\"font-family: courier new, courier;\">isSmaller<\/span>. In contrast, the <span style=\"font-family: courier new, courier;\">operator &lt;<\/span> is quite often applicable, and any type can use the predicate. The <span style=\"font-family: courier new, courier;\">operator &lt;<\/span> and the full specialization are static. This means the ordering is defined at compile time and is encoded in the type or the generic function. In contrast, the extension can be invoked with different predicates. This is a runtime decision. The <span style=\"font-family: courier new, courier;\">operator &lt;<\/span> extends the type, the other both variants the function. The extension with a predicate allows it to order your type in various ways. For example, you can compare strings lexicographically or by their length.<\/p>\n<p>Based on this comparison, a good rule of thumb is to implement an <span style=\"font-family: courier new, courier;\">operator &lt;<\/span> for your types and add an extension to your generic functions if necessary. Therefore, your type behaves <span style=\"font-family: courier new, courier;\">Regular<\/span> according to Alexander Stepanov, and supports customized orderings.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Whats_next\"><\/span>What&#8217;s next?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-rules-for-templates-and-hierarchies\">next post<\/a> is about templates. In particular, it is about template hierarchies.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>My post for today is just loosely coupled to the rules of the C++ core guidelines because they do provide not much content. Inspired by the guidelines, today&#8217;s post concerns a generic isSmaller function.<\/p>\n","protected":false},"author":21,"featured_media":5572,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[],"class_list":["post-5578","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5578","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=5578"}],"version-history":[{"count":0,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5578\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5572"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5578"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5578"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5578"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}