2016-06-09 18 views
1

Auf cppreference Website, wenn es um Direct_Initialization geht, sagt es funktioniert in Schließung Parameter erfassen wie ... {0} Ich denke, das sollte "Lambda-Funktion" sein, aber warum es auch "Schließung" genannt wird?In C++ 11 ist "Lambda-Funktion" gleich mit "Lambda-Ausdruck" und "Schließung"?

Ich habe C++ 11-Standard, den Punkt "Schließung" erschien zuerst in Abschnitt 5.1.2 (Lambda-Ausdruck), die sagt:

The evaluation of a lambda-expression results in a prvalue temporary (12.2). This temporary is called the 
closure object. A lambda-expression shall not appear in an unevaluated operand (Clause 5). [ Note: A 
closure object behaves like a function object (20.8). — end note ] 

So wie "evalute lamdba Ausdruck" zu verstehen? Ist bei dieser "Auswertung" etwas während der Kompilierung oder Laufzeit passiert? Gibt es Unterschiede in C++ 11, unter den Elementen "Lambda-Ausdruck", "Lambda-Funktion" und "Schließung"?

Ich spreche nicht über andere Programmiersprachen wie Closure, nur auf C++ 11 konzentrieren. Danke.

Antwort

0

Lambda-Ausdruck ist wie andere Ausdrücke, wird zur Laufzeit standardmäßig ausgewertet. Auswertung des Ausdrucks 1 + 2 gibt ein int die Wert 3. Auswertung des Lambda-Ausdruck ist [] { return 0; } ein Verschluss Objekt gibt, das auch ein Funktionsobjekt ist, das operator()() eine Funktion, die 0.

Kurz zurückkehrt, ist ein Verschluss-Objekt ein Laufzeitobjekt Wie alle anderen Objekte in C++ ist ein Lambda-Ausdruck ein Ausdruck, dessen Ergebnis ein Closure-Objekt ist.

2

Was für eine Schließung ist (unter Angabe von wikipedia):

In Programmiersprachen, Verschlüssen (auch lexikalische Verschlüsse oder Funktion Schließungen) sind eine Technik für die Umsetzung lexikalischen Namen in Sprachen mit ersten Bindungs -Klasse-Funktionen. Operativ ein Verschluss ist eine Aufzeichnung mit einer Funktion [a] zusammen mit einer Umgebung Speicherung: a Mapping Zuordnen jedes freies Variable von die Funktion (Variablen, die lokal benutzt werden, sondern in einem umschließenden Umfang definiert ist) mit der Wert oder Speicherort, an den der Name gebunden war, als der Abschluss erstellt wurde [b]. Ein Abschluss ermöglicht im Gegensatz zu einer Plain-Funktion der Funktion den Zugriff auf die erfassten Variablen über den Verweis auf den Abschluss, auch wenn die Funktion außerhalb ihres Gültigkeitsbereichs aufgerufen wird.

[a] Die Funktion kann als Referenz auf eine Funktion wie einen Funktionszeiger gespeichert werden.

[b] Diese Namen beziehen sich meist auf Werte, wandelbar Variablen oder Funktionen, kann aber auch andere Einheiten wie Konstanten, Typen, Klassen oder Etiketten sein.

Was ist ein Ausdruck Lambda (unter Angabe von wikipedia):

In Computer-Programmierung, eine anonyme Funktion (Funktionsliteral, Lambda-Abstraktion) ist eine Funktionsdefinition, die ist nicht an eine Kennung gebunden.

Da C++ 11, C++ anonyme Funktionen unterstützt, genannt lambda Ausdrücke, die die Form haben:

[capture](parameters) -> return_type { function_body } 

Ein Beispiel Lambda-Funktion ist wie folgt definiert:

[](int x, int y) -> int { return x + y; } 

Seit C++ 11 unterstützt C++ auch Verschlüsse. Verschlüsse sind zwischen eckigen Klammern [und] in der Deklaration von Lambda definiert. Der Mechanismus ermöglicht die Erfassung dieser Variablen nach Wert oder Referenz. Die folgende Tabelle veranschaulicht dies:

[]  //no variables defined. Attempting to use any external variables in the lambda is an error. 
[x, &y] //x is captured by value, y is captured by reference 
[&]  //any external variable is implicitly captured by reference if used 
[=]  //any external variable is implicitly captured by value if used 
[&, x] //x is explicitly captured by value. Other variables will be captured by reference 
[=, &z] //z is explicitly captured by reference. Other variables will be captured by value 

Résumé

Begriffe Lambda Ausdruck und Lambda-Funktion werden austauschbar verwendet, um bedeutet die Definition/Deklaration einer anonymen Funktion Objekt als:

[capture](parameters) -> return_type { function_body } 

Mit dem Begriff Schließung beziehen wir uns auf die Run-Time-Funktion Objekt durch die Auswertung eines Lambda Ausdruck erstellt.

Jetzt für Lambda zur Kompilierzeit ausgewertet werden, würde dies ein Lambda als konstanten Ausdruck erfordern. Leider sind Lambdas nicht constexpr und können daher nicht zur Kompilierzeit ausgewertet werden. Es gibt jedoch einen Vorschlag an das Komitee N4487, der vorschlägt, dass wir mit der Aufhebung einiger Einschränkungen constexpr Lambdas haben könnten. Das heißt, in Zukunft könnten wir constexpr Lambdas haben, die zur Kompilierungszeit ausgewertet werden könnten.