{"id":5340,"date":"2017-11-04T10:50:39","date_gmt":"2017-11-04T10:50:39","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-rules-for-overloading-and-overload-operators\/"},"modified":"2023-06-26T12:02:35","modified_gmt":"2023-06-26T12:02:35","slug":"c-core-guidelines-rules-for-overloading-and-overload-operators","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-rules-for-overloading-and-overload-operators\/","title":{"rendered":"C++ Core Guidelines: Rules for Overloading and Overload Operators"},"content":{"rendered":"<p>There are ten rules for overloading and overload operators in the C++ core guidelines. Many of them are pretty obvious, but your software may become very unintuitive if you don&#8217;t follow them.<\/p>\n<p><!--more--><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5336\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/mistake.png\" alt=\"mistake\" width=\"500\" height=\"318\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/mistake.png 640w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/mistake-300x191.png 300w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>I&#8217;m pretty surprised to have only ten rules for overloading in the guidelines. I&#8217;m particularly surprised because I had a lot of discussions in the past about the overloading of operators in C++. Additionally, at least MISRA C++, which is heavily used in the automotive and embedded area, forbids operator overloading.<\/p>\n<p>In contrast to the discussion in C++, I have not a discussion in Python about operator overloading in mind, but Python is heavily based on operator overloading. To get an idea. Look at the following special functions starting and ending with two underscores, lovingly called dunder in Python. You must implement them to get a type that behaves like an <span style=\"font-family: courier new,courier;\">int.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5337\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/python.png\" alt=\"python\" width=\"500\" height=\"224\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/python.png 842w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/python-300x135.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/python-768x345.png 768w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>&nbsp;But let me continue with C++. Here are the ten rules.<\/p>\n<ul>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-conventional\">C.160: Define operators primarily to mimic conventional usage<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-symmetric\">C.161: Use nonmember functions for symmetric operators<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-equivalent\">C.162: Overload operations that are roughly equivalent<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-equivalent-2\">C.163: Overload only for operations that are roughly equivalent<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-conversion\">C.164: Avoid conversion operators<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-custom\">C.165: Use <code class=\"highlighter-rouge no-highlight\">using<\/code> for customization points<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-address-of\">C.166: Overload unary <code class=\"highlighter-rouge no-highlight\">&amp;<\/code> only as part of a system of smart pointers and references<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-overload\">C.167: Use an operator for an operation with its conventional meaning<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-namespace\">C.168: Define overloaded operators in the namespace of their operands<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-lambda\">C.170: If you feel like overloading a lambda, use a generic lambda<\/a><\/li>\n<\/ul>\n<p>A lot of the rules are quite obvious; therefore, I often can make it short.<\/p>\n<h2>Overloading and overloaded operators<\/h2>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-conventional\">C.160: Define operators primarily to mimic conventional usage<\/a><\/h3>\n<p>You should follow <a href=\"https:\/\/en.wikipedia.org\/wiki\/Principle_of_least_astonishment\">the principle of least astonishment<\/a>. Or to say it in rule <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-copy-and-move-rules\">C: 61: A copy operation should copy.<\/a> That means after the assignment <span style=\"font-family: courier new,courier;\">x = y, x == y<\/span> should hold.<\/p>\n<p>This was obvious. Right? The following rule sounds easy, but the discussion of it is pretty enlighting.<\/p>\n<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-symmetric\">C.161: Use nonmember functions for symmetric operators<\/a><\/h3>\n<p>Implementing a symmetric operator such as + is impossible inside the class.<\/p>\n<p>Assume that you want to implement a type <span style=\"font-family: courier new,courier;\">MyInt. MyInt<\/span> should support addition with <span style=\"font-family: courier new,courier;\">MyInt<\/span>&#8216;s and built-in <span style=\"font-family: courier new,courier;\">int<\/span>&#8216;s. Let&#8217;s give it a try.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ MyInt.cpp<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> MyInt{\r\n    MyInt(<span style=\"color: #007788; font-weight: bold;\">int<\/span> v)<span style=\"color: #555555;\">:<\/span>val(v){};              <span style=\"color: #0099ff; font-style: italic;\">\/\/ 1<\/span>\r\n    MyInt <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">+<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> MyInt<span style=\"color: #555555;\">&amp;<\/span> oth) <span style=\"color: #006699; font-weight: bold;\">const<\/span> { \r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> MyInt(val <span style=\"color: #555555;\">+<\/span> oth.val);\r\n    }\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> val;\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n\r\n  MyInt myFive <span style=\"color: #555555;\">=<\/span> MyInt(<span style=\"color: #ff6600;\">2<\/span>) <span style=\"color: #555555;\">+<\/span> MyInt(<span style=\"color: #ff6600;\">3<\/span>);\r\n  MyInt myFive2 <span style=\"color: #555555;\">=<\/span> MyInt(<span style=\"color: #ff6600;\">3<\/span>) <span style=\"color: #555555;\">+<\/span> MyInt(<span style=\"color: #ff6600;\">2<\/span>);\r\n  \r\n  MyInt myTen <span style=\"color: #555555;\">=<\/span> myFive <span style=\"color: #555555;\">+<\/span> <span style=\"color: #ff6600;\">5<\/span>;            <span style=\"color: #0099ff; font-style: italic;\">\/\/ 2<\/span>\r\n  MyInt myTen2 <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">5<\/span> <span style=\"color: #555555;\">+<\/span> myFive;           <span style=\"color: #0099ff; font-style: italic;\">\/\/ 3 ERROR<\/span>\r\n  \r\n}\r\n  \r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Because of the implicit conversion constructor (1), expression (2) is valid. In contrast, the last expression (3) is invalid because the <span style=\"font-family: courier new,courier;\">5<\/span> in the expression <span style=\"font-family: courier new,courier;\">5 + myFive<\/span> will not implicitly convert to a <span style=\"font-family: courier new,courier;\">MyInt;<\/span> therefore, I got a compiler error.<\/p>\n<p>Trying to compile the program will fail because <span style=\"font-family: courier new,courier;\">int<\/span> does not have an overloaded + operator for<span style=\"font-family: courier new,courier;\"> MyInt<\/span>.&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5338\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/MyIntError.png\" alt=\"MyIntError\" width=\"600\" height=\"154\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/MyIntError.png 842w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/MyIntError-300x77.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/MyIntError-768x197.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>The minor program has a lot of issues:<\/p>\n<ol>\n<li>The + operator is not symmetric.<\/li>\n<li>The <span style=\"font-family: courier new,courier;\">val<\/span> variable is public.<\/li>\n<li>The conversion constructor is implicit.<\/li>\n<\/ol>\n<p>It&#8217;s pretty easy to overcome the first issues with a non-member operator + that is in the class declared as a friend.<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ MyInt2.cpp<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">MyInt2<\/span>{\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n    MyInt2(<span style=\"color: #007788; font-weight: bold;\">int<\/span> v)<span style=\"color: #555555;\">:<\/span>val(v){};\r\n    <span style=\"color: #006699; font-weight: bold;\">friend<\/span> MyInt2 <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">+<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> MyInt2<span style=\"color: #555555;\">&amp;<\/span> fir, <span style=\"color: #006699; font-weight: bold;\">const<\/span> MyInt2<span style=\"color: #555555;\">&amp;<\/span> sec){ \r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> MyInt2(fir.val <span style=\"color: #555555;\">+<\/span> sec.val);\r\n    }\r\n<span style=\"color: #9999ff;\">private:<\/span>\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> val;\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n\r\n  MyInt2 myFive <span style=\"color: #555555;\">=<\/span> MyInt2(<span style=\"color: #ff6600;\">2<\/span>) <span style=\"color: #555555;\">+<\/span> MyInt2(<span style=\"color: #ff6600;\">3<\/span>);\r\n  MyInt2 myFive2 <span style=\"color: #555555;\">=<\/span> MyInt2(<span style=\"color: #ff6600;\">3<\/span>) <span style=\"color: #555555;\">+<\/span> MyInt2(<span style=\"color: #ff6600;\">2<\/span>);\r\n  \r\n  MyInt2 myTen <span style=\"color: #555555;\">=<\/span> myFive <span style=\"color: #555555;\">+<\/span> <span style=\"color: #ff6600;\">5<\/span>;\r\n  MyInt2 myTen2 <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">5<\/span> <span style=\"color: #555555;\">+<\/span> myFive;           \r\n  \r\n}\r\n  \r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Now, implicit conversion from <span style=\"font-family: courier new,courier;\">int<\/span> to<span style=\"font-family: courier new,courier;\"> MyInt<\/span> kicks in, and the variable <span style=\"font-family: courier new,courier;\">val<\/span> is private. According to rule <a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-conversion\">C.164: Avoid conversion operators<\/a>, you should not use an implicit conversion constructor. By making the conversion constructor in the following example explicit, the example will break.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ MyInt3.cpp<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">MyInt3<\/span>{\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">explicit<\/span> MyInt3(<span style=\"color: #007788; font-weight: bold;\">int<\/span> v)<span style=\"color: #555555;\">:<\/span>val(v){};           <span style=\"color: #0099ff; font-style: italic;\">\/\/ 1<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">friend<\/span> MyInt3 <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">+<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> MyInt3<span style=\"color: #555555;\">&amp;<\/span> fir, <span style=\"color: #006699; font-weight: bold;\">const<\/span> MyInt3<span style=\"color: #555555;\">&amp;<\/span> sec){ \r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> MyInt3(fir.val <span style=\"color: #555555;\">+<\/span> sec.val);\r\n    }\r\n<span style=\"color: #9999ff;\">private:<\/span>\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> val;\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n\r\n  MyInt3 myFive <span style=\"color: #555555;\">=<\/span> MyInt3(<span style=\"color: #ff6600;\">2<\/span>) <span style=\"color: #555555;\">+<\/span> MyInt3(<span style=\"color: #ff6600;\">3<\/span>);\r\n  MyInt3 myFive2 <span style=\"color: #555555;\">=<\/span> MyInt3(<span style=\"color: #ff6600;\">3<\/span>) <span style=\"color: #555555;\">+<\/span> MyInt3(<span style=\"color: #ff6600;\">2<\/span>);\r\n  \r\n  MyInt3 myTen <span style=\"color: #555555;\">=<\/span> myFive <span style=\"color: #555555;\">+<\/span> <span style=\"color: #ff6600;\">5<\/span>;                   <span style=\"color: #0099ff; font-style: italic;\">\/\/ 2<\/span>\r\n  MyInt3 myTen2 <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">5<\/span> <span style=\"color: #555555;\">+<\/span> myFive;                  <span style=\"color: #0099ff; font-style: italic;\">\/\/ 3<\/span>\r\n  \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Thanks to the explicit conversion operator, implicit conversion from <span style=\"font-family: courier new,courier;\">int<\/span> to <span style=\"font-family: courier new,courier;\">MyInt<\/span> will not happen; therefore, lines (2) and (3) fail.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5339\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/MyInt3Error.png\" alt=\"MyInt3Error\" width=\"600\" height=\"306\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/MyInt3Error.png 893w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/MyInt3Error-300x153.png 300w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>At least I followed the rule, and my operator is symmetric.<\/p>\n<p>One obvious way to solve the original challenge is to implement two additional + operators for <span style=\"font-family: courier new,courier;\">MyInt4<\/span>. One should take an int as left, and one should take an int as correct argument.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ MyInt4.cpp<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">MyInt4<\/span>{\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">explicit<\/span> MyInt4(<span style=\"color: #007788; font-weight: bold;\">int<\/span> v)<span style=\"color: #555555;\">:<\/span>val(v){};           <span style=\"color: #0099ff; font-style: italic;\">\/\/ 1<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">friend<\/span> MyInt4 <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">+<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> MyInt4<span style=\"color: #555555;\">&amp;<\/span> fir, <span style=\"color: #006699; font-weight: bold;\">const<\/span> MyInt4<span style=\"color: #555555;\">&amp;<\/span> sec){ \r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> MyInt4(fir.val <span style=\"color: #555555;\">+<\/span> sec.val);\r\n    }\r\n    <span style=\"color: #006699; font-weight: bold;\">friend<\/span> MyInt4 <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">+<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> MyInt4<span style=\"color: #555555;\">&amp;<\/span> fir, <span style=\"color: #007788; font-weight: bold;\">int<\/span> sec){\r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> MyInt4(fir.val <span style=\"color: #555555;\">+<\/span> sec);\r\n    }\r\n     <span style=\"color: #006699; font-weight: bold;\">friend<\/span> MyInt4 <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">+<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span> fir, <span style=\"color: #006699; font-weight: bold;\">const<\/span> MyInt4<span style=\"color: #555555;\">&amp;<\/span> sec){\r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> MyInt4(fir <span style=\"color: #555555;\">+<\/span> sec.val);\r\n    }\r\n<span style=\"color: #9999ff;\">private:<\/span>\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> val;\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n\r\n  MyInt4 myFive <span style=\"color: #555555;\">=<\/span> MyInt4(<span style=\"color: #ff6600;\">2<\/span>) <span style=\"color: #555555;\">+<\/span> MyInt4(<span style=\"color: #ff6600;\">3<\/span>);\r\n  MyInt4 myFive2 <span style=\"color: #555555;\">=<\/span> MyInt4(<span style=\"color: #ff6600;\">3<\/span>) <span style=\"color: #555555;\">+<\/span> MyInt4(<span style=\"color: #ff6600;\">2<\/span>);\r\n  \r\n  MyInt4 myTen <span style=\"color: #555555;\">=<\/span> myFive <span style=\"color: #555555;\">+<\/span> <span style=\"color: #ff6600;\">5<\/span>;                   <span style=\"color: #0099ff; font-style: italic;\">\/\/ 2<\/span>\r\n  MyInt4 myTen2 <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">5<\/span> <span style=\"color: #555555;\">+<\/span> myFive;                  <span style=\"color: #0099ff; font-style: italic;\">\/\/ 3<\/span>\r\n  \r\n}\r\n<\/pre>\n<\/div>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-equivalent\">C.162: Overload operations that are roughly equivalent, <\/a>and <a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-equivalent-2\">C.163: Overload only for operations that are roughly equivalent<\/a><\/h3>\n<p>This time, I can make it short. Equivalent operations should have the same name. Or the other way around. Non-equivalent operations should not have the same name.<\/p>\n<p>Here is an example from the guidelines:<\/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: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">print<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span> a);\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">print<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span> a, <span style=\"color: #007788; font-weight: bold;\">int<\/span> base);\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">print<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> string<span style=\"color: #555555;\">&amp;<\/span>);\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Invoking <span style=\"font-family: courier new,courier;\">print(arg)<\/span> with an argument feels like generic programming. You do not have to care which version of <span style=\"font-family: courier new,courier;\">print<\/span> will be used.<\/p>\n<p>This will not hold for the three following functions because they have different names:<\/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: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">print_int<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span> a);\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">print_based<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span> a, <span style=\"color: #007788; font-weight: bold;\">int<\/span> base);\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">print_string<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> string<span style=\"color: #555555;\">&amp;<\/span>);\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>If non-equivalent operations have the same name, the names may be too general or wrong. This is confusing and error-prone.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>The following rule is quite essential: <a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-conversion\">C.164: Avoid conversion operators<\/a>. I already mentioned it in rule C.161. You should not use an implicit conversion constructor and &#8211; this is new &#8211; an implicit conversion operator. Why? I will write about it in the <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-more-rules-to-overloading\">next post<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There are ten rules for overloading and overload operators in the C++ core guidelines. Many of them are pretty obvious, but your software may become very unintuitive if you don&#8217;t follow them.<\/p>\n","protected":false},"author":21,"featured_media":5336,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[499,501],"class_list":["post-5340","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c","tag-classes","tag-overloading"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5340","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=5340"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5340\/revisions"}],"predecessor-version":[{"id":6853,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5340\/revisions\/6853"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5336"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5340"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5340"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5340"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}