Stroutrupinterview
-
!rr!rr_. schrieb:
die capture clause [...] könnte entfallen, wenn man sich per Default für alle Bindungen auf "by reference" einigen könnte.
Kann man sich aber nicht. Jedenfalls gefällt mir Dein vorschlag so gar nicht. Denk mal an so Sachen wie std::async. Einige Funktionsobjekte sollten schon ihre eigenen Kopien mitschleppen.
-
krümelkacker schrieb:
Was hat das eine mit dem anderen zu tun?
ich habe es geahnt
-
ach, jetzt weiß ich, was du meinst
- ja, nein, wieso genau müssen denn Variablen des äußeren Kontexts überhaupt spezifiziert werden, um sie in der anonymen Funktion zu verwenden? Ihre Sichtbarkeit würde ausreichen, um sie innerhalb der anonymen Funktion zu lesen und/oder ändern.
-
ok, jetzt hab ich's.
O(outer foo &x, outer int y, float z){ x = bla; return y + z; }
wobei:
O = reservierter Name für anonyme Funktionen
outer => "Zugriff auf äußeren Kontext"
outer foo &x => "capture by reference"
outer int y => "caputere by value"Damit könnte die herkömmliche Schreibweise
für benannte Funktionen einfach weiterverwendet werden.
-
Das könnte die Signatur aber ziemlich ausarten lassen. Ich find's aktuell ganz gut gelöst, ein "[&]" ist ja kurz und knackig.
-
!rr!rr_. schrieb:
ok, jetzt hab ich's.
O(outer foo &x, outer int y, float z){ x = bla; return y + z; }
Damit könnte die herkömmliche Schreibweise
für benannte Funktionen einfach weiterverwendet werden.Was ist denn mit dem Rückgabetypen? Den kann man zZ ja nur weglassen, wenn der Funktionskörper ein einziges "return ...;" ist. Die "capture-clause" hier in den ()-Klammern unterzubringen gefällt mir gar nicht. Das sollte man schon trennen. "O" und "outer" als Schlüsselwörter zu verbraten, ist IMO auch keine gute Idee.
So, wie es aktuell aussieht, gefällt es mir viel besser:
[&x,y](float z)->float{ x=bla; return y+z; }
Ich muss den Typ von x und y nicht noch extra angeben. Der ist dem Compiler ja schon bekannt. Außerdem sehe ich hier sofort, wieviele Parameter der Funktionsaufruf-Operator erwartet.
Bzgl "anonyme Funktionen", der aktuelle Entwurf erlaubt eine Konvertierung eines Lambdaausdrucks zu einem Funktionszeiger, falls das "effective capture set" leer ist. Wenn ich das richtig verstehe, soll dann folgendes funktionieren:
void foo(void(*funptr)()) { funptr(); } int main() { foo([]{ cout << "hello world!\n"; }); }
Das einzige, was ich ein bisschen vermisse, ist ein "move-capture". [&x] bedeutet, dass das Funktionsobjekt eine Referenz auf x speichert. [y] bedeutet, dass das Funktionsobjekt eine Kopie von y speichert. Da wir aber auch "move-only"-Typen in C++ haben werden (wie zB streams, unique_ptr, unique_lock, etc) und mit Move-Konstructions Zeit sparen können, wäre es nett gewesen, wenn wir auch eine Syntax hätten, die ein Objekt nicht kopiert, sondern "move"t.
-
krümelkacker schrieb:
So, wie es aktuell aussieht, gefällt es mir viel besser:
[&x,y](float z)->float{ x=bla; return y+z; }
Haskell-Fans werden sich mit dem "->" wie zu Hause fühlen
Bei herkömmlicher Syntax kann man den Rückgabetyp doch auch angeben:
float O(outer foo &x, outer int y, float z){ x = bla; return y + z; }