Lambda bindings extrahieren?



  • Kann man an die Bindings eines Lambdas rankommen?

    int i = 0;
    auto lam[i](){};
    auto ex = lam.i; // <- der gedanke.
    

    Was ist der Gültigkeitsbereich von i in lam?





  • struct A
    {
        int i;
    };
    
    template <typename LamT>
    union U
    {
        LamT l;
        A a;
    
        U(LamT&& l)
            : l{std::move(l)}
        {}
    };
    
    int main()
    {
    
        int i = 2;
        auto lam = [i](){std::cout << "hello\n";};
        U<decltype(lam)> u{std::move(lam)};
        std::cout << u.a.i << "\n";
    
        u.l();
    
        return 0;
    }
    

    eugh, mir wird schlecht. bla bla undefined behaviour.
    War ja auch nur ne hypothetische frage.


  • Mod

    Wenn Du derartige Funktionalitaet benötigst, schreib doch einfach Deinen eigenen Funktor. Lambdas sind intransparent, damit ihr Verhalten leichter zu verstehen ist.

    Ansonsten koennte man nur hoffen, dass du ein konkreteres Einsatzbeispiel zeigst, damit man die Alternativen diskutieren kann.



  • War nur ein Gedanke der hierbei entstanden ist:

    readJsonBody(req, res, [this, req, res](json const& body)
    {
        /* ... */
    });
    

    Der Gedanke war die ersten beiden Parameter zu sparen und sie aus dem lambda zu ziehn.
    Hab mich entschieden nichts zu tun.

    Schon alleine weil man das nicht ansatzweise erahnen kann dass das passiert. Wenn man den Inhalt des lambda captures ändert, entstehen sonst
    plötzlich bugs die (vielleicht) durch die kompilierung kommen aber man nur schwer sehen kann was los ist.

    Nich jede Idee ist eine gute Idee.
    Trotzdem wollte ich wissen obs geht.


  • Mod

    Die Idee ist Schwachsinn, gerade wenn readJsonBody die beiden Variablen letztlich sowieso kopiert. Was Du oben stehen hast ist schon die optimale Form.



  • @Columbo
    Ich denke immer drüber nach dopplungen im code zu reduzieren. Das ist Automatismus der erstmal nichts damit zu tun hat ob es sinnvoll ist.
    Und fürs Auge steht da erstmal "req, res, req, res".
    req und res sind übrigens pointer.



  • @5cript
    Falls es so ist dass es kaum einen sinnvollen Anwendungsfall gibt wo der an readJsonBody übergebene Funktor req und res nicht braucht, dann könnte man es auch umdrehen: readJsonBody könnte req und res als zusätzliche Parameter an den Funktor übergeben. Kann sinn machen, muss aber nicht.

    Weniger zu tippen wird das dadurch aber auch nicht - man muss ja dann im Funktor die beiden zusätzlichen Parameter deklarieren. Der Haupt-Nutzen wäre dass so sichergestellt ist dass der Aufrufer nicht unterschiedliche Werte übergibt. (Wobei man es auch als Feature sehen könnte dass man unterschiedliche Werte verwenden kann. Kommt drauf an was req und res hier sind und ob es für die korrekte Funktion wichtig ist dass die in den Funktor gebundenen Werte immer identisch zu den readJsonBody-Argumenten sind.)

    Wenn readJsonBody hauptsächlich mit ad-hoc Lambdas verwendet wird, würde ich es vermutlich nicht machen, d.h. den Code einfach so lassen wie gezeigt. Falls das relevant ist hätte es allerdings die Vorteile dass man dadurch Funktoren für unterschiedliche req und res wiederverwenden kann sowie dass man sich bei "manuell" implementierten Funktoren u.U. den Konstruktor spart bzw. dieser einfacher wird.



  • @hustbaer sagte in Lambda bindings extrahieren?:

    @5cript
    Falls es so ist dass es kaum einen sinnvollen Anwendungsfall gibt wo der an readJsonBody übergebene Funktor req und res nicht braucht.

    Es gibt sogar exakt 0 Fälle (zumindest für res(ponse))

    req ist request und res ist response einer HTTP Request Abhandlung.
    Jeder Request muss mit einer Antwort durch 'response' abgeschlossen werden by requirement, oder die Verbindung wird nicht geschlossen.

    Es ist 99% unmöglich andere/falsche req&res zu verwenden oder zu missverwenden.

    Da die Abhandlungen meist sehr kompakt sind wären Funktoren Overkill.
    Ich nutze meine selbst geschrieben HTTP Server Bibliothek.

    server.post("/api/workspace/observe", [this](auto req, auto res)
    {
        readJsonBody(req, res, [this, req, res](json const& body)
        {
            res->status(500).send("observer feature pending");
        });
    })
    

Anmelden zum Antworten