{"id":5319,"date":"2017-09-22T19:22:18","date_gmt":"2017-09-22T19:22:18","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-comparison-swap-and-hash\/"},"modified":"2023-06-26T12:05:58","modified_gmt":"2023-06-26T12:05:58","slug":"c-core-guidelines-comparison-swap-and-hash","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-comparison-swap-and-hash\/","title":{"rendered":"C++ Core Guidelines: Comparison, Swap, and Hash"},"content":{"rendered":"<p>This post will be about comparisons, swap, and hash. That means I conclude with his post my treatise about default operations rules in C++.<\/p>\n<p><!--more--><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" alignright size-full wp-image-5318\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/09\/scales-310962_640.png\" alt=\"scales 310962 640\" width=\"400\" height=\"401\" style=\"float: right;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/09\/scales-310962_640.png 639w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/09\/scales-310962_640-300x300.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/09\/scales-310962_640-150x150.png 150w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/>&nbsp;<\/p>\n<p>Here are the nine rules.<\/p>\n<ul>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-eqdefault\">C.80: Use <code class=\"highlighter-rouge no-highlight\">=default<\/code> if you have to be explicit about using the default semantics<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-delete\">C.81: Use <code class=\"highlighter-rouge no-highlight\">=delete<\/code> when you want to disable default behavior (without wanting an alternative)<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-ctor-virtual\">C.82: Don\u2019t call virtual functions in constructors and destructors<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-swap\">C.83: For value-like types, consider providing a <code class=\"highlighter-rouge no-highlight\">noexcept<\/code> swap function<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-swap-fail\">C.84: A <code class=\"highlighter-rouge no-highlight\">swap<\/code> may not fail<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-swap-noexcept\">C.85: Make <code class=\"highlighter-rouge no-highlight\">swap<\/code> <code class=\"highlighter-rouge no-highlight\">noexcept<\/code><\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-eq\">C.86: Make <code class=\"highlighter-rouge no-highlight\">==<\/code> symmetric with respect of operand types and <code class=\"highlighter-rouge no-highlight\">noexcept<\/code><\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-eq-base\">C.87: Beware of <code class=\"highlighter-rouge no-highlight\">==<\/code> on base classes<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-hash\">C.89: Make a <code class=\"highlighter-rouge no-highlight\">hash<\/code> <code class=\"highlighter-rouge no-highlight\">noexcept<\/code><\/a><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>Let&#8217;s dive into the details.<\/p>\n<h2>Default operation rules:<\/h2>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-eqdefault\">C.80: Use <code class=\"highlighter-rouge no-highlight\">=default<\/code> if you have to be explicit about using the default semantics<\/a><\/h3>\n<p>Do you remember the <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-constructors-assignments-and-desctructors\">rule of five<\/a>? It means if you define one of the five special member functions, you must define all.<\/p>\n<p>Here is the point.<\/p>\n<p>When I implement the destructor, such as in the following example, I have to define the copy and move constructor and assignment operator.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Tracer<\/span> {\r\n    string message;\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n    Tracer(<span style=\"color: #006699; font-weight: bold;\">const<\/span> string<span style=\"color: #555555;\">&amp;<\/span> m) <span style=\"color: #555555;\">:<\/span> message{m} { cerr <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"entering \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> message <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>; }\r\n    <span style=\"color: #555555;\">~<\/span>Tracer() { cerr <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"exiting \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> message <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>; }\r\n\r\n    Tracer(<span style=\"color: #006699; font-weight: bold;\">const<\/span> Tracer<span style=\"color: #555555;\">&amp;<\/span>) <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">default<\/span>;\r\n    Tracer<span style=\"color: #555555;\">&amp;<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">=<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> Tracer<span style=\"color: #555555;\">&amp;<\/span>) <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">default<\/span>;\r\n    Tracer(Tracer<span style=\"color: #555555;\">&amp;&amp;<\/span>) <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">default<\/span>;\r\n    Tracer<span style=\"color: #555555;\">&amp;<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">=<\/span>(Tracer<span style=\"color: #555555;\">&amp;&amp;<\/span>) <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">default<\/span>;\r\n};\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>That was easy! Right? But I can also do it alone, which is at least uninteresting and error-prone.&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Tracer2<\/span> {\r\n    string message;\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n    Tracer2(<span style=\"color: #006699; font-weight: bold;\">const<\/span> string<span style=\"color: #555555;\">&amp;<\/span> m) <span style=\"color: #555555;\">:<\/span> message{m} { cerr <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"entering \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> message <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>; }\r\n    <span style=\"color: #555555;\">~<\/span>Tracer2() { cerr <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"exiting \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> message <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>; }\r\n\r\n    Tracer2(<span style=\"color: #006699; font-weight: bold;\">const<\/span> Tracer2<span style=\"color: #555555;\">&amp;<\/span> a) <span style=\"color: #555555;\">:<\/span> message{a.message} {}\r\n    Tracer2<span style=\"color: #555555;\">&amp;<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">=<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> Tracer2<span style=\"color: #555555;\">&amp;<\/span> a) { message <span style=\"color: #555555;\">=<\/span> a.message; <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #555555;\">*<\/span><span style=\"color: #006699; font-weight: bold;\">this<\/span>; }\r\n    Tracer2(Tracer2<span style=\"color: #555555;\">&amp;&amp;<\/span> a) <span style=\"color: #555555;\">:<\/span>message{a.message} {}\r\n    Tracer2<span style=\"color: #555555;\">&amp;<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">=<\/span>(Tracer2<span style=\"color: #555555;\">&amp;&amp;<\/span> a) { message <span style=\"color: #555555;\">=<\/span> a.message; <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #555555;\">*<\/span><span style=\"color: #006699; font-weight: bold;\">this<\/span>; }\r\n};\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-delete\">C.81: Use <code class=\"highlighter-rouge no-highlight\">=delete<\/code> when you want to disable default behavior (without wanting an alternative)<\/a><\/h3>\n<p>Sometimes, you want to disable the default operations. Here comes <span style=\"font-family: courier new,courier;\">delete<\/span> into the play. C++ eats its own dog food. The copy constructor of types such as locks, mutexes, promises, or futures is set to <span style=\"font-family: courier new,courier;\">delete. <\/span>The same holds true for the smart pointer <span style=\"font-family: courier new,courier;\">std::unique_ptr: std::unique_ptr(const std::unique_ptr&amp;) = delete. <br \/><\/span><\/p>\n<p>You can use delete to create strange types. Instances of <span style=\"font-family: courier new,courier;\">Immortal<\/span> cannot be destroyed.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Immortal<\/span> {\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n    <span style=\"color: #555555;\">~<\/span>Immortal() <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">delete<\/span>;   <span style=\"color: #0099ff; font-style: italic;\">\/\/ do not allow destruction<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ ...<\/span>\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">use<\/span>()\r\n{\r\n    Immortal ugh;   <span style=\"color: #0099ff; font-style: italic;\">\/\/ error: ugh cannot be destroyed<\/span>\r\n    Immortal<span style=\"color: #555555;\">*<\/span> p <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">new<\/span> Immortal{};\r\n    <span style=\"color: #006699; font-weight: bold;\">delete<\/span> p;       <span style=\"color: #0099ff; font-style: italic;\">\/\/ error: cannot destroy *p<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-ctor-virtual\">C.82: Don\u2019t call virtual functions in constructors and destructors<\/a><\/h3>\n<p>This rule is quite similar to rule <a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-factory\">C.50: Use a factory function if you need \u201cvirtual behavior\u201d during initialization<\/a> which I presented in the post <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-constructors\">C++ Core Guidelines: Constructors<\/a>.<\/p>\n<p>The next three rules are about <span style=\"font-family: courier new,courier;\">swap<\/span> functions. Let&#8217;s do it together.<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-swap\">C.83: For value-like types, consider providing a <code class=\"highlighter-rouge no-highlight\">noexcept<\/code> swap function, <\/a><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-swap-fail\">C.84: A <code class=\"highlighter-rouge no-highlight\">swap<\/code> may not fail, and <\/a><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-swap-noexcept\">C.85: Make <code class=\"highlighter-rouge no-highlight\">swap<\/code> <code class=\"highlighter-rouge no-highlight\">noexcept<\/code><\/a><\/h3>\n<p>A swap function is quite handy.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span> <span style=\"color: #006699; font-weight: bold;\">typename<\/span> T <span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> std<span style=\"color: #555555;\">::<\/span>swap(T <span style=\"color: #555555;\">&amp;<\/span> a, T <span style=\"color: #555555;\">&amp;<\/span> b) noexcept {\r\n    T tmp(std<span style=\"color: #555555;\">::<\/span>move(a));\r\n    a <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>move(b);\r\n    b <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>move(tmp);\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The C++ standard offers more than 40 specializations for <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/algorithm\/swap\">std::swap<\/a>. You can use it as a building block for many idioms, such as copy construction\/assignment. A swap function should not fail; therefore, you must declare it as <span style=\"font-family: courier new,courier;\">noexcept.<\/span><\/p>\n<p>Here is an example of a move assignment operation using <span style=\"font-family: courier new,courier;\">std::swap<\/span>. &nbsp;<span style=\"font-family: courier new,courier;\">pdata<\/span> points to an array.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Cont<\/span>{     \r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n  Cont<span style=\"color: #555555;\">&amp;<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">=<\/span>(Cont<span style=\"color: #555555;\">&amp;&amp;<\/span> rhs);\r\n \r\n<span style=\"color: #9999ff;\">private:<\/span>\r\n  <span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #555555;\">*<\/span>pData;           <span style=\"color: #0099ff; font-style: italic;\"><\/span>\r\n};\r\n\r\nCont<span style=\"color: #555555;\">&amp;<\/span> Cont<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">=<\/span>(Cont<span style=\"color: #555555;\">&amp;&amp;<\/span> rhs){\r\n  std<span style=\"color: #555555;\">::<\/span>swap(pData, rhs.pData);\r\n  <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #555555;\">*<\/span><span style=\"color: #006699; font-weight: bold;\">this<\/span>;\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-eq\">C.86: Make <code class=\"highlighter-rouge no-highlight\">==<\/code> symmetric with respect of operand types and <code class=\"highlighter-rouge no-highlight\">noexcept<\/code><\/a><\/h3>\n<p>If you don&#8217;t want to surprise your user, you should make the <span style=\"font-family: courier new,courier;\">== operato<\/span>r symmetric.<\/p>\n<p>Here is an unintuitive<span style=\"font-family: courier new,courier;\"> == operator<\/span>, which is defined inside the class.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">MyNumber<\/span> {\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> num;\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n    MyNumber(<span style=\"color: #007788; font-weight: bold;\">int<\/span> n)<span style=\"color: #555555;\">:<\/span> num(n){};\r\n    <span style=\"color: #007788; font-weight: bold;\">bool<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">==<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> MyNumber<span style=\"color: #555555;\">&amp;<\/span> rhs) const { <span style=\"color: #006699; font-weight: bold;\">return<\/span> num <span style=\"color: #555555;\">==<\/span> rhs.num; }\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n<span style=\"color: #555555;\"><\/span><span style=\"color: #ff6600;\"><\/span><span style=\"color: #555555;\"><\/span><span style=\"color: #ff6600;\"> <\/span><span style=\"color: #006699; font-weight: bold;\"><\/span><span style=\"color: #555555;\"><\/span>MyNumber(<span style=\"color: #ff6600;\">5<\/span>) <span style=\"color: #555555;\">==<\/span> <span style=\"color: #ff6600;\">5<\/span>;\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ 5 == MyNumber(5);<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The call <span style=\"font-family: courier new,courier;\">MyNumber(5) == 5<\/span> is valid because the constructor converts the <span style=\"font-family: courier new,courier;\">int<\/span> argument to an instance of <span style=\"font-family: courier new,courier;\">MyNumber. <\/span>The last line gives an error.&nbsp; The comparison operator for natural numbers will not accept an instance of <span style=\"font-family: courier new,courier;\">MyNumber<\/span>.<\/p>\n<p>The elegant way to solve this asymmetry is to declare a friend <code>operator==<\/code> inside the class <span style=\"font-family: courier new,courier;\">MyNumber.<\/span> <span style=\"font-family: courier new,courier;\"><\/span>Here is the second version of <span style=\"font-family: courier new,courier;\">MyNumber.<\/span><\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">MyNumber<\/span> {\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> num;\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n    MyNumber(<span style=\"color: #007788; font-weight: bold;\">int<\/span> n)<span style=\"color: #555555;\">:<\/span> num(n){};\r\n    <span style=\"color: #007788; font-weight: bold;\">bool<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">==<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> MyNumber<span style=\"color: #555555;\">&amp;<\/span> rhs) <span style=\"color: #006699; font-weight: bold;\">const<\/span> { <span style=\"color: #006699; font-weight: bold;\">return<\/span> num <span style=\"color: #555555;\">==<\/span> rhs.num; }\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>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&amp;<\/span> lhs, <span style=\"color: #006699; font-weight: bold;\">const<\/span> MyNumber<span style=\"color: #555555;\">&amp;<\/span> rhs){ \r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> lhs <span style=\"color: #555555;\">==<\/span> rhs.num; \r\n    }\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n    MyNumber(<span style=\"color: #ff6600;\">5<\/span>) <span style=\"color: #555555;\">==<\/span> <span style=\"color: #ff6600;\">5<\/span>;\r\n    <span style=\"color: #ff6600;\">5<\/span> <span style=\"color: #555555;\">==<\/span> MyNumber(<span style=\"color: #ff6600;\">5<\/span>);\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>&nbsp;The surprises continue.<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-eq-base\">C.87: Beware of <code class=\"highlighter-rouge no-highlight\">==<\/code> on base classes<\/a><\/h3>\n<p>Writing a foolproof <span style=\"font-family: courier new,courier;\">== operator<\/span> for a hierarchy is hard. The guidelines give an excellent example of such a challenging job. Here is the hierarchy.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">B<\/span> {\r\n    string name;\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> number;\r\n    <span style=\"color: #006699; font-weight: bold;\">virtual<\/span> <span style=\"color: #007788; font-weight: bold;\">bool<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">==<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> B<span style=\"color: #555555;\">&amp;<\/span> a) <span style=\"color: #006699; font-weight: bold;\">const<\/span>\r\n    {\r\n         <span style=\"color: #006699; font-weight: bold;\">return<\/span> name <span style=\"color: #555555;\">==<\/span> a.name <span style=\"color: #555555;\">&amp;&amp;<\/span> number <span style=\"color: #555555;\">==<\/span> a.number;\r\n    }\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ ...<\/span>\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">D<\/span> <span style=\"color: #555555;\">:<\/span>B {\r\n    <span style=\"color: #007788; font-weight: bold;\">char<\/span> character;\r\n    <span style=\"color: #006699; font-weight: bold;\">virtual<\/span> <span style=\"color: #007788; font-weight: bold;\">bool<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">==<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> D<span style=\"color: #555555;\">&amp;<\/span> a) <span style=\"color: #006699; font-weight: bold;\">const<\/span>\r\n    {\r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> name <span style=\"color: #555555;\">==<\/span> a.name <span style=\"color: #555555;\">&amp;&amp;<\/span> number <span style=\"color: #555555;\">==<\/span> a.number <span style=\"color: #555555;\">&amp;&amp;<\/span> character <span style=\"color: #555555;\">==<\/span> a.character;\r\n    }\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ ...<\/span>\r\n};\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Let&#8217;s try it out.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0px; line-height: 125%;\">B b <span style=\"color: #555555;\">=<\/span> ...\r\nD d <span style=\"color: #555555;\">=<\/span> ...\r\nb <span style=\"color: #555555;\">==<\/span> d;      <span style=\"color: #0099ff; font-style: italic;\">\/\/ compares name and number, ignores d's character            \/\/ (1)<\/span>\r\nd <span style=\"color: #555555;\">==<\/span> b;      <span style=\"color: #0099ff; font-style: italic;\">\/\/ error: no == defined                                       \/\/ (2)<\/span><span style=\"color: #555555;\"><\/span><span style=\"color: #0099ff; font-style: italic;\">&nbsp;<br \/><\/span><span style=\"color: #000000;\">D d2;<br \/>d == d2;  <em>  <\/em><\/span><span style=\"color: #0099ff; font-style: italic;\">\/\/ compares, name, number, and character<\/span><span style=\"color: #000000;\"><br \/><\/span>B<span style=\"color: #555555;\">&amp;<\/span> b2 <span style=\"color: #555555;\">=<\/span> d2; <br \/>b2 <span style=\"color: #555555;\">==<\/span> d;    <span style=\"color: #0099ff; font-style: italic;\">\/\/ compares name and number, ignores d2's and d's character    \/\/ (1)<\/span><\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Comparing instances of <span style=\"font-family: courier new,courier;\">B<\/span> or instances of <span style=\"font-family: courier new,courier;\">D<\/span> will work. But mixing instances of <span style=\"font-family: courier new,courier;\">B<\/span> and <span style=\"font-family: courier new,courier;\">D<\/span> will not work as expected. Using B&#8217;s <span style=\"font-family: courier new,courier;\">== operator<\/span> ignores <span style=\"font-family: courier new,courier;\">D<\/span>&#8216;s <span style=\"font-family: courier new,courier;\">character<\/span> (1). Using <span style=\"font-family: courier new,courier;\">D<\/span>&#8216;s operator will not work for instances of <span style=\"font-family: courier new,courier;\">B <\/span>(3). The last line is quite tricky. The <span style=\"font-family: courier new,courier;\">== operator<\/span> of <span style=\"font-family: courier new,courier;\">B<\/span> is used. Why? The <span style=\"font-family: courier new,courier;\">== operator<\/span> of <span style=\"font-family: courier new,courier;\">D<\/span> overwrote the <span style=\"font-family: courier new,courier;\">== operator<\/span> of B.Really? No! Both operators have different signatures. One taking an instance of <span style=\"font-family: courier new,courier;\">B<\/span>; the other taking an instance of <span style=\"font-family: courier new,courier;\">D<\/span>. <span style=\"font-family: courier new,courier;\">D<\/span>&#8216;s version will not overwrite <span style=\"font-family: courier new,courier;\">B<\/span>&#8216;s version.<\/p>\n<p>This observation will also hold for the other five comparison operators: !=, &lt;, &lt;=, &gt;, and &gt;=.<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-hash\">C.89: Make a <code class=\"highlighter-rouge no-highlight\">hash<\/code> <code class=\"highlighter-rouge no-highlight\">noexcept<\/code><\/a><\/h3>\n<p>Hash functions are implicitly used by unordered associative containers such as <span style=\"font-family: courier new,courier;\">std::unordered_map<\/span>. The user doesn&#8217;t expect that they will throw. If you want to use your own type as a key in an unordered associative container, you must define a hash function for the key.<\/p>\n<p>Do it by using the <span style=\"font-family: courier new,courier;\">std::hash<\/span> function for the attributes of your class and combining them with ^ (xor).<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">struct<\/span> MyKey{\r\n  <span style=\"color: #007788; font-weight: bold;\">int<\/span> valInt <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">5<\/span>;\r\n  <span style=\"color: #007788; font-weight: bold;\">double<\/span> valDou <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">5.5<\/span>;\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> MyHash{\r\n  std<span style=\"color: #555555;\">::<\/span><span style=\"color: #007788; font-weight: bold;\">size_t<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span>()(MyKey m) <span style=\"color: #006699; font-weight: bold;\">const<\/span> {\r\n    std<span style=\"color: #555555;\">::<\/span>hash<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> hashVal1;\r\n    std<span style=\"color: #555555;\">::<\/span>hash<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">double<\/span><span style=\"color: #555555;\">&gt;<\/span> hashVal2;\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #cc00ff;\">hashVal1<\/span>(m.valInt) <span style=\"color: #555555;\">^<\/span> hashVal2(m.valDou);\r\n  }\r\n};\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>Following the guidelines, the next topic should be containers and other resource handles, but only the names of the rules are available. Therefore I will skip this part and go straight to lambda expressions in the <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-function-objects-and-lambas\">next post<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post will be about comparisons, swap, and hash. That means I conclude with his post my treatise about default operations rules in C++.<\/p>\n","protected":false},"author":21,"featured_media":5318,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[499],"class_list":["post-5319","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c","tag-classes"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5319","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=5319"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5319\/revisions"}],"predecessor-version":[{"id":6859,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5319\/revisions\/6859"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5318"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5319"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5319"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5319"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}