{"id":3967,"date":"2019-01-07T19:30:02","date_gmt":"2019-01-07T18:30:02","guid":{"rendered":"http:\/\/roboblog.fatal-fury.de\/?p=3967"},"modified":"2019-01-07T19:30:02","modified_gmt":"2019-01-07T18:30:02","slug":"c-guns-pass-function-objects-per-forwarding-references","status":"publish","type":"post","link":"http:\/\/roboblog.fatal-fury.de\/?p=3967","title":{"rendered":"C++ Guns: Pass function objects per Forwarding references!"},"content":{"rendered":"<p>I say: <strong>Pass (template) function objects per Forwarding references!<\/strong> and not per value. The reason is simple: it works also with function objects with state.<\/p>\n<p><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/reference\">https:\/\/en.cppreference.com\/w\/cpp\/language\/reference<\/a><\/p>\n<p>A little example will show it:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#include &lt;iostream&gt;\r\n#include &lt;random&gt;\r\nusing namespace std;\r\n\r\ntemplate&lt;typename Function&gt;\r\nauto perValue(Function f) {\r\n  return f();\r\n}\r\n\r\ntemplate&lt;typename Function&gt;\r\nauto perForwardReference(Function&amp;&amp; f) {\r\n  return f();\r\n}\r\n\r\nint main() {\r\n  std::minstd_rand gen(1156823295);\r\n  \r\n  cout &lt;&lt; &quot;Generate 5 random numbers:\\n&quot;;\r\n  cout &lt;&lt; &quot;calls to perValue:\\n&quot;;\r\n  for(int i=0; i &lt; 5; i++) {\r\n    cout &lt;&lt; perValue(gen) &lt;&lt; &quot;\\n&quot;;\r\n  }\r\n  \r\n  cout &lt;&lt; &quot;calls to perForwardReference:\\n&quot;;\r\n  for(int i=0; i &lt; 5; i++) {\r\n    cout &lt;&lt; perForwardReference(gen) &lt;&lt; &quot;\\n&quot;;\r\n  }  \r\n}\r\n<\/pre>\n<blockquote><p>\nGenerate 5 random numbers:<br \/>\ncalls to perValue:<br \/>\n4<br \/>\n4<br \/>\n4<br \/>\n4<br \/>\n4<br \/>\ncalls to perForwardReference:<br \/>\n4<br \/>\n193084<br \/>\n730423176<br \/>\n870612250<br \/>\n1216431607\n<\/p><\/blockquote>\n<p><a href=\"https:\/\/xkcd.com\/221\/\"><img decoding=\"async\" src=\"https:\/\/imgs.xkcd.com\/comics\/random_number.png\" alt=\"\" \/><\/a><\/p>\n<p>It doesn\u2019t work because the random number generate object has a state. The call to function <em>perValue()<\/em> change this state on a copy of the generator. And not the one, we pass as argument. But there is no compile time error. Not a single warning. That's the worst case IMO.<\/p>\n<p>The C++ standard and Scott Meyers book \"Effective STL\" recommend to pass by value. IMO for historical reasons.<\/p>\n<blockquote><p>\nC++11 \u00a725.1\/10:<br \/>\n    [ Note: Unless otherwise specified, algorithms that take function objects as arguments are permitted to copy those function objects freely. Programmers for whom object identity is important should consider using a wrapper class that points to a noncopied implementation object such as reference_wrapper<T> (20.8.3), or some equivalent solution. \u2014end note ]\n<\/p><\/blockquote>\n<p><a href=\"https:\/\/stackoverflow.com\/questions\/17626667\/why-function-objects-should-be-pass-by-value\">stackoverflow: why function objects should be pass-by-value<\/a><\/p>\n<p>The standard should be updated and the book is horrible outdated. It was written 2008 and forward references come with C++2011. The old solution is to wrap the function into something which can be pass by value, but also change the state. We have now (2011) <em>std::function<\/em> for that task. And not this ugly thing in the book.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I say: Pass (template) function objects per Forwarding references! and not per value. The reason is simple: it works also with function objects with state. https:\/\/en.cppreference.com\/w\/cpp\/language\/reference A little example will show it: #include &lt;iostream&gt; #include &lt;random&gt; using namespace std; template&lt;typename Function&gt; auto perValue(Function f) { return f(); } template&lt;typename Function&gt; auto perForwardReference(Function&amp;&amp; f) { return [&hellip;]<\/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-3967","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\/3967","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=3967"}],"version-history":[{"count":11,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/3967\/revisions"}],"predecessor-version":[{"id":3978,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/3967\/revisions\/3978"}],"wp:attachment":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3967"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3967"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3967"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}