{"id":5318,"date":"2024-07-26T14:41:35","date_gmt":"2024-07-26T13:41:35","guid":{"rendered":"http:\/\/roboblog.fatal-fury.de\/?p=5318"},"modified":"2024-07-26T14:41:35","modified_gmt":"2024-07-26T13:41:35","slug":"c-guns-overloading-friend-operator-for-class-template-the-right-way","status":"publish","type":"post","link":"http:\/\/roboblog.fatal-fury.de\/?p=5318","title":{"rendered":"C++ Guns: Overloading friend operator for class template - the right way"},"content":{"rendered":"<h2>Goal<\/h2>\n<p>Overload operator +=, << etc. as free function for a templated class with private member variables without boilerplate code. <br \/>\nChoose free function to achieve less coupling than with member functions. <br \/>\nIn the example you can imagine the Type as Array2D for a use case.<\/p>\n<h2>Solution<\/h2>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\ntemplate&lt;typename T&gt;\r\nclass Type {\r\npublic:\r\n    \/\/ free function form of the operator\r\n    \/\/ no repeat of the template parameters for class Type necessary\r\n    \/\/ with the friend keyword this is still a free function but can \r\n    \/\/ access private variables like a member function\r\n    friend Type&amp; operator+=(Type&amp; lhs, double value) {\r\n        lhs.data += value; \/\/ can access private member variable\r\n        return x;\r\n    }\r\n\r\nprivate:\r\n    double data = 0;\r\n};\r\n\r\n\r\nvoid f(Type&lt;double&gt;&amp; x) {\r\n    x += 2.0;\r\n}\r\n<\/pre>\n<h2>Not a Solution<\/h2>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n\/\/ forward declaration, not usual\r\ntemplate&lt;typename T&gt;\r\nclass Type;\r\n\r\n\/\/ Definition of the function is placed bevor the definition of the type. \r\n\/\/ This is also not usual but needed for the friend declaration later in the code.\r\n\/\/ Repeat of the template parameter.\r\ntemplate&lt;typename T&gt;\r\ninline Type&lt;T&gt;&amp; operator+=(Type&lt;T&gt;&amp; lhs, double value) {\r\n    lhs.data += value;    \r\n    return lhs;\r\n}\r\n\r\ntemplate&lt;typename T&gt;\r\nclass Type {\r\n\r\nprivate:\r\n    double data = 0;\r\n\r\n    \/\/ templated friend declaration. watch the necessary but very unusual &lt;&gt; here.    \r\n    friend Type&amp; operator+= &lt;&gt;(Type&amp; lhs, double value);\r\n};\r\n\r\nvoid f(Type&lt;double&gt;&amp; x) {\r\n    x += 2.0;\r\n}\r\n<\/pre>\n<p>C.4: Make a function a member only if it needs direct access to the representation of a class <a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-member\">https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-member<\/a><br \/>\nSources: <a href=\"https:\/\/stackoverflow.com\/questions\/4660123\/overloading-friend-operator-for-class-template\">https:\/\/stackoverflow.com\/questions\/4660123\/overloading-friend-operator-for-class-template<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Goal Overload operator +=,<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[17],"class_list":["post-5318","post","type-post","status-publish","format-standard","hentry","category-allgemein","tag-cpp"],"_links":{"self":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/5318","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5318"}],"version-history":[{"count":12,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/5318\/revisions"}],"predecessor-version":[{"id":5330,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/5318\/revisions\/5330"}],"wp:attachment":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5318"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5318"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5318"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}