C++Guns – RoboBlog

11.03.2017

C++17 Guns - std::optional Part IV

Filed under: Allgemein — Tags: — Thomas @ 13:03

Der Übergang von cpl::optional nach std::optional ist schnell gemacht. Nur beim Zugriff ändert sich sichtlich etwas. Wir können 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 << "Redundante Information Schachttiefe vs DMP-SMP";
    }
}

Bei operator-> denkt man gleich an Pointer. Bisher war es aber immer operator. gewesen. Und der extra Umweg über value() ist auch too verbose. Wenn wir mehr Richtung funktionaler Programmierung denken, dann ergibt sich die Möglichkeit, den ekligen Zugriff in einer Funktion zu verstecken. Diese Funktion bekommt beide Punkte, und eine Funktion, was mit den Punkten gemacht werden soll.
Das könnte in etwa so aussehen:


template
void maybeBoth(const optional& x, const optional& y, Function func) {
    if(x and y) {
        func(*x, *y);
    }
}

maybeBoth(schacht.DMP(), schacht.SMP(),
    [&schacht](const Punkt& DMP, const Punkt& SMP) {
        if(fuzzyEqual(abs(DMP.point.z - SMP.point.z), schacht.tiefe) == false) {
             cout << "Redundante Information Schachttiefe vs DMP-SMP";
        }
    }
);

Hmm mit der Einrückung hab ich so meine Probleme. Jedenfalls wäre das die kürzeste Variante, denn der maybeBoth Ausdruck ist nur eine Zeile. Der komische Zugriff ist weg, dafür müssen 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.
Hm 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ück gibt, ist hier nicht ersichtlich. Die logische Verknüpfung, dass DMP UND SMP existieren müssen ist hier nicht ersichtlich. Sicher, man kann das in der Dokumentation so festhalten von maybeBoth() und nach einer weile hat man das drauf.
Aber für ein winziges Stück Code, was ich maximal schnell hinschreiben will (Zeit ist Lebenszeit), ist das doch nichts. Womöglich sollte ich "maybe" durch "if" ersetzen. Also ifBoth(DMP, SMP)? Oder ifBothExist(DMP, SMP) ? Sieht schon besser aus. Voll viel Arbeit...

Aber nochmal kurz zurück an den Anfang. Was gewinne ich dadurch? Dass T in cpl::optional default construktible sein muss? Hm. MUSS es das wirklich? Durch die Vererbung wäre das doch angebracht. Sicher funktioniert cpl::optional nicht bei final Klassen. Es ist eben keine generelle Lösung, sondern eine, die jeder schnell versteht und umsetzen kann.

Eine Sache bleibt noch aus. Was passiert, wenn ich neben DMP und SMP auch noch RAP und SA brauche? Und ich möchte nicht die Schleife in Schacht::x vier mal laufen lassen. In nur einer Schleife soll überprüft werden, ob alle geforderten Punkte existieren und auf einmal, alle als optional, zurück gegeben werden. Ob das gut funktioniert?

No Comments

No comments yet.

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

Powered by WordPress