{"id":3272,"date":"2017-11-23T19:43:10","date_gmt":"2017-11-23T18:43:10","guid":{"rendered":"http:\/\/roboblog.fatal-fury.de\/?p=3272"},"modified":"2017-11-26T14:10:07","modified_gmt":"2017-11-26T13:10:07","slug":"c-guns-re-abstraction-design-and-implementation-repeat-teil-2","status":"publish","type":"post","link":"http:\/\/roboblog.fatal-fury.de\/?p=3272","title":{"rendered":"C++ Guns: RE: Abstraction design and implementation: `repeat` Teil 2"},"content":{"rendered":"<p>In <a href=\"http:\/\/roboblog.fatal-fury.de\/?p=3263\">Teil 1<\/a> ging es um die allgemeinen Probleme einer simplen for() Schleife.<br \/>\nIn Teil 2 werde ich Vittorio Romeo Ansatz verfolgen, eine repeat() Funktion zu erstellen, die eine Funktion f genau N mal aufruft. <\/p>\n<p>Syntaktisch und semantisch w\u00fcrde ich diesen Code okay finden:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#include &lt;type_traits&gt;\r\n#include &lt;iostream&gt;\r\n\r\nvoid f() {\r\n  cout &lt;&lt; &quot;f()\\n&quot;;\r\n}\r\n\r\ntemplate&lt;typename Func&gt;\r\nvoid repeat(int n, Func&amp;&amp; f) {\r\n  for(int i=0; i &lt; n; ++i) {\r\n    f();\r\n  }\r\n}\r\n\r\nint main() {\r\n  repeat(10, f);\r\n}\r\n<\/pre>\n<p>Die Funktion f wird einfach 10 mal aufgerufen. Das war einfach.<\/p>\n<p>Sobald ich mehr tun will, wirds kompliziert.<\/p>\n<p>Schritt f\u00fcr Schritt. Wir werden sehen wann es nicht mehr klappt.<br \/>\nM\u00f6chte ich der Funktion f einen Parameter mitgeben, der nicht von der aktuellen Iterationen abh\u00e4ngt, l\u00e4sst sich das leicht mit einem Lambda realisieren, welches ein Interface darstellt. Dieses Interface bildet meine Funktion f(int) auf eine Funktion ohne Argument ab. Also genau so eine Funktion, welche repeat() erwartet.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nvoid f(int parameter) {\r\n  cout &lt;&lt; &quot;f() parameter &quot; &lt;&lt; parameter &lt;&lt; &quot;\\n&quot;;\r\n}\r\n\r\nint main() {\r\n  int parameter = 42;\r\n  repeat(10, &#x5B;parameter]() {\r\n    f(parameter);\r\n  });\r\n}\r\n<\/pre>\n<p>Die Funktion repeat() \u00e4ndert sich nicht. Das ist schon einmal ein gutes Zeichen.<br \/>\nJetzt wird es kritisch. Ich m\u00f6chte neben dem Parameter noch die Laufvariablen der repeat Funktion mit nach f() \u00fcbergeben. Daf\u00fcr benutze ich wieder ein Lambda welches das Interface bereit stellt und auch if constexpr und std::is_invocable_v. Also hight end C++17 Shit :D Mal sehn obs kappt.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nvoid f(int i, int parameter) {\r\n  cout &lt;&lt; &quot;f() i: &quot; &lt;&lt; i &lt;&lt; &quot; parameter: &quot; &lt;&lt; parameter &lt;&lt; &quot;\\n&quot;;\r\n}\r\n\r\ntemplate&lt;typename Func&gt;\r\nvoid repeat(int n, Func&amp;&amp; f) {\r\n  for(int i=0; i &lt; n; ++i) {\r\n    \r\n    if constexpr(std::is_invocable_v&lt;Func&amp;&amp;, int&gt;) {\r\n      f(i);\r\n    } else {\r\n      f();\r\n    }\r\n  }\r\n}\r\n\r\nint main() {\r\n  int parameter = 42;\r\n  repeat(10, &#x5B;parameter](int i) {\r\n    f(parameter, i);\r\n  });\r\n}\r\n<\/pre>\n<p>Der Code compiliert mit einem C++17 Compiler (gcc 7) und liefert folgende Ausgabe:<\/p>\n<pre><code>\r\nf() i: 42 parameter: 0\r\nf() i: 42 parameter: 1\r\nf() i: 42 parameter: 2\r\nf() i: 42 parameter: 3\r\nf() i: 42 parameter: 4\r\nf() i: 42 parameter: 5\r\nf() i: 42 parameter: 6\r\nf() i: 42 parameter: 7\r\nf() i: 42 parameter: 8\r\nf() i: 42 parameter: 9\r\n<\/code><\/pre>\n<p>Das ist nicht das, was ich wollte. Ich habe absichtlich die Funktions Argumente <code>parameter<\/code> und <code>i<\/code> vertauscht und der Compiler hats nicht gemerkt! Wie sollte er auch. Die Variable i ist nur ein int Type und hat keinerlei Semantik einer Laufvariablen.<\/p>\n<p>Das hat mich am Artikel \"abstraction design and implementation: `repeat`\" auch so stark gest\u00f6rt. Damit es ist super einfach lazy Bugs zu erzeugen und am Ende hat man nichts gewonnen.<\/p>\n<p>Im dritten Teil will ich versuchen das C++ Typesystem zu nutzen, um die Semantik einer Laufvariablen auszudr\u00fccken und im letzten Beispiel einen Compilerfehler zu erzwingen.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In Teil 1 ging es um die allgemeinen Probleme einer simplen for() Schleife. In Teil 2 werde ich Vittorio Romeo Ansatz verfolgen, eine repeat() Funktion zu erstellen, die eine Funktion f genau N mal aufruft. Syntaktisch und semantisch w\u00fcrde ich diesen Code okay finden: #include &lt;type_traits&gt; #include &lt;iostream&gt; void f() { cout &lt;&lt; &quot;f()\\n&quot;; } [&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-3272","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\/3272","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=3272"}],"version-history":[{"count":7,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/3272\/revisions"}],"predecessor-version":[{"id":3280,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/3272\/revisions\/3280"}],"wp:attachment":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3272"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3272"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3272"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}