{"id":2838,"date":"2017-03-11T13:53:07","date_gmt":"2017-03-11T12:53:07","guid":{"rendered":"http:\/\/roboblog.fatal-fury.de\/?p=2838"},"modified":"2017-03-11T13:53:07","modified_gmt":"2017-03-11T12:53:07","slug":"c17-guns-stdoptional-part-iv","status":"publish","type":"post","link":"http:\/\/roboblog.fatal-fury.de\/?p=2838","title":{"rendered":"C++17 Guns - std::optional Part IV"},"content":{"rendered":"<p>Der \u00dcbergang von cpl::optional nach std::optional ist schnell gemacht. Nur beim Zugriff \u00e4ndert sich sichtlich etwas. Wir k\u00f6nnen operator*, operator->, value() oder value_or() nutzen. Das sieht alles nicht gut aus:<\/p>\n<pre><code>\r\nif(DMP and SMP) {\r\n    if(fuzzyEqual(abs(DMP->point.z - SMP.value().point.z), schacht.tiefe) == false) {\r\n        cout << \"Redundante Information Schachttiefe vs DMP-SMP\";\r\n    }\r\n}\r\n<\/code><\/pre>\n<p>Bei operator-> denkt man gleich an Pointer. Bisher war es aber immer operator. gewesen. Und der extra Umweg \u00fcber value() ist auch too verbose. Wenn wir mehr Richtung funktionaler Programmierung denken, dann ergibt sich die M\u00f6glichkeit, den ekligen Zugriff in einer Funktion zu verstecken. Diese Funktion bekommt beide Punkte, und eine Funktion, was mit den Punkten gemacht werden soll.<br \/>\nDas k\u00f6nnte in etwa so aussehen:<\/p>\n<pre><code>\r\ntemplate<class T1, class T2, class Function>\r\nvoid maybeBoth(const optional<T1>& x, const optional<T2>& y, Function func) {\r\n    if(x and y) {\r\n        func(*x, *y);\r\n    }\r\n}\r\n\r\nmaybeBoth(schacht.DMP(), schacht.SMP(),\r\n    [&schacht](const Punkt& DMP, const Punkt& SMP) {\r\n        if(fuzzyEqual(abs(DMP.point.z - SMP.point.z), schacht.tiefe) == false) {\r\n             cout << \"Redundante Information Schachttiefe vs DMP-SMP\";\r\n        }\r\n    }\r\n);\r\n<\/code><\/pre>\n<p>Hmm mit der Einr\u00fcckung hab ich so meine Probleme. Jedenfalls w\u00e4re das die k\u00fcrzeste Variante, denn der maybeBoth Ausdruck ist nur eine Zeile. Der komische Zugriff ist weg, daf\u00fcr m\u00fcssen wir eine Funktion, oder ein Lambda definieren. Welches wiederum ein Funktionskopf mit Parameter braucht. Das ist wieder sehr verbose... In anderen Sprachen ist die Syntax angeblich viel besser.<br \/>\nHm es ist anders zu lesen. Ungewohnt. Funktional eben. Da steht kein if() mehr. Das \"Wenn\" steckt jetz in \"maybeBoth\". Aber maybe was? Dass schacht.DMP() ein optional zur\u00fcck gibt, ist hier nicht ersichtlich. Die logische Verkn\u00fcpfung, dass DMP UND SMP existieren m\u00fcssen ist hier nicht ersichtlich. Sicher, man kann das in der Dokumentation so festhalten von maybeBoth() und nach einer weile hat man das drauf.<br \/>\nAber f\u00fcr ein winziges St\u00fcck Code, was ich maximal schnell hinschreiben will (Zeit ist Lebenszeit), ist das doch nichts. Wom\u00f6glich sollte ich \"maybe\" durch \"if\" ersetzen. Also ifBoth(DMP, SMP)? Oder ifBothExist(DMP, SMP) ? Sieht schon besser aus. Voll viel Arbeit...<\/p>\n<p>Aber nochmal kurz zur\u00fcck an den Anfang. Was gewinne ich dadurch? Dass T in cpl::optional<T> default construktible sein muss? Hm. MUSS es das wirklich? Durch die Vererbung w\u00e4re das doch angebracht. Sicher funktioniert cpl::optional nicht bei final Klassen. Es ist eben keine generelle L\u00f6sung, sondern eine, die jeder schnell versteht und umsetzen kann.<\/p>\n<p>Eine Sache bleibt noch aus. Was passiert, wenn ich neben DMP und SMP auch noch RAP und SA brauche? Und ich m\u00f6chte nicht die Schleife in Schacht::x vier mal laufen lassen. In nur einer Schleife soll \u00fcberpr\u00fcft werden, ob alle geforderten Punkte existieren und auf einmal, alle als optional, zur\u00fcck gegeben werden. Ob das gut funktioniert?<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Der \u00dcbergang von cpl::optional nach std::optional ist schnell gemacht. Nur beim Zugriff \u00e4ndert sich sichtlich etwas. Wir k\u00f6nnen operator*, operator->, value() oder value_or() nutzen. Das sieht alles nicht gut aus: if(DMP and SMP) { if(fuzzyEqual(abs(DMP->point.z - SMP.value().point.z), schacht.tiefe) == false) { cout denkt man gleich an Pointer. Bisher war es aber immer operator. gewesen. Und [&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-2838","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\/2838","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=2838"}],"version-history":[{"count":3,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/2838\/revisions"}],"predecessor-version":[{"id":3672,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/2838\/revisions\/3672"}],"wp:attachment":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2838"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2838"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2838"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}