C ++ Lambdas, Capturing, Smart Ptrs und der Stack: Warum funktioniert das?

8

Ich habe mit einigen der neuen Funktionen in C ++ 11 herumgespielt, und ich habe versucht, das folgende Programm zu schreiben, in der Erwartung, dass es nicht funktioniert. Zu meiner Überraschung ist es (in GCC 4.6.1 auf Linux x86 mit dem Flag "std = c ++ 0x"):

%Vor%

Ich habe erwartet, dass 'from_ref' gelöscht wird, wenn jede Ausführung des zurückgegebenen Lambda ausgeführt wird. Hier ist meine Argumentation: Sobald count_up_in_2s ausgeführt wird, wird from_ref vom Stapel entfernt, aber da das zurückgegebene Lambda nicht sofort ausgeführt wird, da es zurückgegeben wird, gibt es keine weitere Referenz für einen kurzen Zeitraum, bis die gleiche Referenz existiert zurückgeschoben, wenn das Lambda tatsächlich ausgeführt wird, also sollte der Referenzzähler von shared_ptr nicht auf null drücken und dann die Daten löschen?

Es sei denn, C ++ 11s Lambda-Capturing ist viel schlauer, als ich es zu schätzen weiß, und wenn es so ist, werde ich zufrieden sein. Wenn dies der Fall ist, kann ich dann davon ausgehen, dass die Variablenerfassung von C ++ 11 alle lexikalischen Scoping- / Closure-Tricks auf Lisp zulässt, solange sich / sowas / um dynamisch zugewiesenen Speicher kümmert? Kann ich davon ausgehen, dass alle erfassten Referenzen am Leben bleiben, bis das Lambda selbst gelöscht wird, so dass ich smart_ptrs in der oben genannten Weise verwenden kann?

Wenn das so ist, wie ich es denke, bedeutet das nicht, dass C ++ 11 eine ausdrucksstarke Programmierung höherer Ordnung ermöglicht? Wenn dem so ist, denke ich, dass das C ++ 11-Komitee eine hervorragende Arbeit geleistet hat =)

    
Louis 19.12.2011, 04:13
quelle

3 Antworten

7

Das Lambda fängt from_ref nach Wert ein, also erstellt es eine Kopie. Wegen dieser Kopie ist der ref count nicht 0, wenn from_ref zerstört wird, es ist 1 wegen der Kopie, die immer noch im Lambda existiert.

    
Seth Carnegie 19.12.2011, 04:16
quelle
4

Folgendes:

%Vor%

entspricht meistens dem:

%Vor%

Dabei ist __uniqueLambdaType1432 ein Programm - global eindeutiger Typ, der sich von allen anderen, sogar anderen Lambda-Typen unterscheidet, die von einem lexikalisch identischen Lambda-Ausdruck erzeugt werden. Der tatsächliche Name steht dem Programmierer nicht zur Verfügung, und außer dem Objekt, das aus dem ursprünglichen Lambda-Ausdruck resultiert, können keine anderen Instanzen davon erzeugt werden, da der Konstruktor tatsächlich mit Compiler-Magie verborgen ist.

    
JohannesD 19.12.2011 12:24
quelle
1

from_ref wird vom Wert erfasst.

Ihre Argumentation funktioniert, wenn Sie

ersetzen %Vor%

mit

%Vor%     
キキジキ 15.10.2012 16:42
quelle