{"id":6498,"date":"2023-01-16T08:33:08","date_gmt":"2023-01-16T08:33:08","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/argument-dependent-lookup-and-hidden-friends\/"},"modified":"2023-01-16T08:33:08","modified_gmt":"2023-01-16T08:33:08","slug":"argument-dependent-lookup-and-hidden-friends","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/argument-dependent-lookup-and-hidden-friends\/","title":{"rendered":"Argument-Dependent Lookup and the Hidden Friend Idiom"},"content":{"rendered":"<p>Argument-Dependent Lookup (ADL), also known as Koenig Lookup, is a set of &#8220;magical&#8221; rules for the lookup of unqualified functions based on their function arguments.<\/p>\n<p><!--more--><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6493\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/12\/GeneralIdioms.png\" alt=\"GeneralIdioms\" width=\"650\" height=\"331\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/12\/GeneralIdioms.png 1233w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/12\/GeneralIdioms-300x153.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/12\/GeneralIdioms-1024x521.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/12\/GeneralIdioms-768x391.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>The Hidden Friend Idiom is based on Argument-Dependent Lookup (ADL). Therefore, let&#8217;s start this post with ADL.<\/p>\n<h2>Argument-Dependent Lookup<\/h2>\n<p>Have you ever wondered why the following program works?<\/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%;\"><span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> \"<span style=\"color: #cc3300;\">Hello world<\/span>\";\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Why should the program not work? The overloaded output operator <code>operator&lt;&lt;<\/code> is defined in the <code>std<\/code> namespace. The question is, therefore: How is the appropriate overloaded output operator for <code>std::string<\/code> found? You may already assume it.<\/p>\n<p>Wikipedia has a nice definition of ADL:<\/p>\n<ul>\n<li><strong>Argument-Dependent Lookup<\/strong>: In the C++ programming language, <b>argument-dependent lookup<\/b> (<b>ADL<\/b>), or <b>argument-dependent name lookup<\/b>, applies to the lookup of an unqualified function name depending on the types of the arguments given to the function call. This behavior is also known as <b>Koenig lookup<\/b>, as it is often attributed to <a href=\"https:\/\/en.wikipedia.org\/wiki\/Andrew_Koenig_(programmer)\" title=\"Andrew Koenig (programmer)\">Andrew Koenig<\/a>, though he is not its inventor.(<a href=\"https:\/\/en.wikipedia.org\/wiki\/Argument-dependent_name_lookup\">https:\/\/en.wikipedia.org\/wiki\/Argument-dependent_name_lookup<\/a>)<\/li>\n<\/ul>\n<p>Let&#8217;s analyze this. Here is a simple example of applying ADL:<\/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%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ adl.cpp<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">namespace<\/span> MyNamespace {\r\n    <span style=\"color: #006699; font-weight: bold;\">struct<\/span> MyStruct {};\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">function<\/span>(MyStruct) {}\r\n}   \r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> main() {\r\n\r\n    MyNamespace<span style=\"color: #555555;\">::<\/span>MyStruct obj;  \r\n    function(obj);    <span style=\"color: #0099ff;\"> \/\/ (1)<\/span>\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The call<code> function(obj)<\/code> in line (1) would fail without Argument-Dependent Lookup. Thanks to ADL, the lookup for unqualified function names includes the namespace of their arguments in addition to the usual <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/unqualified_lookup\">unqualified name lookup<\/a>. Consequentially, the name function is found in the namespace <code>MyNamespace<\/code>.<\/p>\n<p>Now, we know what ADL means. But this does not solve our original challenge. Why does the simple &#8220;Hello World&#8221; program work?<\/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%;\"><span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> \"<span style=\"color: #cc3300;\">Hello world<\/span>\";\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Let&#8217;s try it out with C++ Insights:<a href=\"https:\/\/cppinsights.io\/s\/bfb25e37\">https:\/\/cppinsights.io\/s\/bfb25e37<\/a><\/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%;\"><span style=\"color: #009999;\">#include &lt;iostream&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><span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">&lt;&lt;<\/span>(std<span style=\"color: #555555;\">::<\/span>cout, <span style=\"color: #cc3300;\">\"Hello world\"<\/span>); <span style=\"color: #0099ff;\"> \/\/ (1)<\/span>\r\n  <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #ff6600;\">0<\/span>;\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The call&nbsp; <code>std::cout &lt;&lt; \"Hello world\";<\/code> is equivalent to the function call <code>operator&lt;&lt;(std::cout, \"Hello world\"); <\/code>(line 1)<code>. <\/code>ADL regards the namespace of its arguments that includes in our concrete case <code>std::cout. <\/code><\/p>\n<p>Finally, let me write about the Hidden Friend Idiom.<\/p>\n<p>&nbsp;<\/p>\n<h2>Hidden Friend Idiom<\/h2>\n<p>Argument-Dependend Lookup extends the public interface of a class: non-member functions or non-member operators extend the public interface of that class. Now, the Hidden Friend Idiom kicks in:<\/p>\n<p>Friend functions or operators defined inside the class have two special properties:<\/p>\n<ol>\n<li>They can access the private members of the class.<\/li>\n<li>They are non-member functions or operators.<\/li>\n<\/ol>\n<p>The second point is pretty unknown, and I regularly have to explain it when I give a class.&nbsp; A <code>friend<\/code> function defined inside the class has interesting consequences for the overloading of operators. Friend operators defined inside the class can access the private members of the class, are non-member functions, and are found by Argument-Dependent Lookup.<\/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: 0px; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ hiddenFriend.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;\">MyDistance<\/span>{\r\n <span style=\"color: #9999ff;\">public:<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">explicit<\/span> MyDistance(<span style=\"color: #007788; font-weight: bold;\">double<\/span> i)<span style=\"color: #555555;\">:<\/span>m(i){}\r\n\r\n    <span style=\"color: #006699; font-weight: bold;\">friend<\/span> MyDistance <span style=\"color: #006699; font-weight: bold;\">operator<\/span> <span style=\"color: #555555;\">+<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> MyDistance<span style=\"color: #555555;\">&amp;<\/span> a, <span style=\"color: #006699; font-weight: bold;\">const<\/span> MyDistance<span style=\"color: #555555;\">&amp;<\/span> b){         <em><span style=\"color: #0099ff;\">\/\/ (1)<\/span><\/em>\r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> MyDistance(a.m <span style=\"color: #555555;\">+<\/span> b.m);\r\n    }\r\n    \r\n    <span style=\"color: #006699; font-weight: bold;\">friend<\/span> MyDistance <span style=\"color: #006699; font-weight: bold;\">operator<\/span> <span style=\"color: #555555;\">-<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> MyDistance<span style=\"color: #555555;\">&amp;<\/span> a, <span style=\"color: #006699; font-weight: bold;\">const<\/span> MyDistance<span style=\"color: #555555;\">&amp;<\/span> b){         <em><span style=\"color: #0099ff;\">\/\/ (2)<\/span><\/em>\r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> MyDistance(a.m <span style=\"color: #555555;\">-<\/span> b.m);\r\n    }\r\n\r\n    <span style=\"color: #006699; font-weight: bold;\">friend<\/span> std<span style=\"color: #555555;\">::<\/span>ostream<span style=\"color: #555555;\">&amp;<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">&lt;&lt;<\/span> (std<span style=\"color: #555555;\">::<\/span>ostream <span style=\"color: #555555;\">&amp;<\/span>out, <span style=\"color: #006699; font-weight: bold;\">const<\/span> MyDistance<span style=\"color: #555555;\">&amp;<\/span> myDist){  <em><span style=\"color: #0099ff;\">\/\/ (3)<\/span><\/em>\r\n        out <span style=\"color: #555555;\">&lt;&lt;<\/span> myDist.m <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" m\"<\/span>;\r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> out;\r\n    }\r\n    \r\n <span style=\"color: #9999ff;\">private:<\/span>\r\n    <span style=\"color: #007788; font-weight: bold;\">double<\/span> m;\r\n\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\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"MyDistance(5.5) + MyDistance(5.5): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> MyDistance(<span style=\"color: #ff6600;\">5.5<\/span>) <span style=\"color: #555555;\">+<\/span> MyDistance(<span style=\"color: #ff6600;\">5.5<\/span>) <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;  <em><span style=\"color: #0099ff;\">\/\/ (4)<\/span><\/em>\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"MyDistance(5.5) - MyDistance(5.5): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> MyDistance(<span style=\"color: #ff6600;\">5.5<\/span>) <span style=\"color: #555555;\">-<\/span> MyDistance(<span style=\"color: #ff6600;\">5.5<\/span>) <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;  <em><span style=\"color: #0099ff;\">\/\/ (5)<\/span><\/em>\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>All three operators in lines (1), (2), and (3) are friends. The corresponding operators (<code>+<\/code>) in line (4) and (<code>-<\/code>) in line (5) are found as expected.<\/p>\n<p>C++ Insights shows once more the magic of operator overloading: <a href=\"https:\/\/cppinsights.io\/s\/50aae5ed\">https:\/\/cppinsights.io\/s\/50aae5ed<\/a><\/p>\n<p>In particular, the addition in line (4) (<code>MyDistance(5.5) + MyDistance(5.5)<\/code>) is transformed into: <code>operator+(MyDistance(5.5), MyDistance(5.5)).<\/code><\/p>\n<p>Finally, here is the output of the program:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6496\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/01\/hiddenFriend.png\" alt=\"hiddenFriend\" width=\"400\" height=\"195\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/01\/hiddenFriend.png 472w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/01\/hiddenFriend-300x146.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>On the contrary, let me remove the friend declaration from the <code>overloaded+<\/code> operator.<\/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;\">MyDistance<\/span>{\r\n <span style=\"color: #9999ff;\">public:<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">explicit<\/span> MyDistance(<span style=\"color: #007788; font-weight: bold;\">double<\/span> i)<span style=\"color: #555555;\">:<\/span>m(i){}\r\n\r\n    MyDistance <span style=\"color: #006699; font-weight: bold;\">operator<\/span> <span style=\"color: #555555;\">+<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> MyDistance<span style=\"color: #555555;\">&amp;<\/span> a, <span style=\"color: #006699; font-weight: bold;\">const<\/span> MyDistance<span style=\"color: #555555;\">&amp;<\/span> b){        \r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> MyDistance(a.m <span style=\"color: #555555;\">+<\/span> b.m);\r\n    }\r\n    \r\n    <span style=\"color: #006699; font-weight: bold;\">friend<\/span> MyDistance <span style=\"color: #006699; font-weight: bold;\">operator<\/span> <span style=\"color: #555555;\">-<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> MyDistance<span style=\"color: #555555;\">&amp;<\/span> a, <span style=\"color: #006699; font-weight: bold;\">const<\/span> MyDistance<span style=\"color: #555555;\">&amp;<\/span> b){      \r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> MyDistance(a.m <span style=\"color: #555555;\">-<\/span> b.m);\r\n    }\r\n\r\n    <span style=\"color: #006699; font-weight: bold;\">friend<\/span> std<span style=\"color: #555555;\">::<\/span>ostream<span style=\"color: #555555;\">&amp;<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">&lt;&lt;<\/span> (std<span style=\"color: #555555;\">::<\/span>ostream <span style=\"color: #555555;\">&amp;<\/span>out, <span style=\"color: #006699; font-weight: bold;\">const<\/span> MyDistance<span style=\"color: #555555;\">&amp;<\/span> myDist){ \r\n        out <span style=\"color: #555555;\">&lt;&lt;<\/span> myDist.m <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" m\"<\/span>;\r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> out;\r\n    }\r\n    \r\n <span style=\"color: #9999ff;\">private:<\/span>\r\n    <span style=\"color: #007788; font-weight: bold;\">double<\/span> m;\r\n\r\n};\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Now, the compilation fails:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6497\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/01\/hiddenFriendBroken.png\" alt=\"hiddenFriendBroken\" width=\"650\" height=\"157\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/01\/hiddenFriendBroken.png 1346w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/01\/hiddenFriendBroken-300x73.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/01\/hiddenFriendBroken-1024x248.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/01\/hiddenFriendBroken-768x186.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>The compiler essentially complains in the first line that the definition of the <code>operator+<\/code> can only have zero or one argument (<code>hiddenFriend:9:16<\/code>). Without the friend declaration, the <code>operator+<\/code> is a member function, and as such, it has an implicit <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/this\"><code>this<\/code> <\/a>pointer. This means that the <code>operator+<\/code> has in sum three arguments. That is not valid c++. Consequentially, the compiler does not find the appropriate<code> operator+<\/code> (<code>hiddenFriend:32:75<\/code>).<\/p>\n<h2>What&#8217;s Next?<\/h2>\n<p>In addition to the Hidden Friend Idiom, C++ has many more idioms for class design. In my next post, I will write about the Rule of Zero, Five, or Six.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Argument-Dependent Lookup (ADL), also known as Koenig Lookup, is a set of &#8220;magical&#8221; rules for the lookup of unqualified functions based on their function arguments.<\/p>\n","protected":false},"author":21,"featured_media":6493,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[379],"tags":[],"class_list":["post-6498","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-patterns"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6498","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=6498"}],"version-history":[{"count":0,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6498\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/6493"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=6498"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=6498"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=6498"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}