2015-02-23 25 views
21

Gemäß dem C++ 11-Standard können Lambda-Ausdrücke Variablen im umschließenden Gültigkeitsbereich mithilfe der Erfassungsliste, der Parameterliste oder beiden verwenden.C++ Lambdas: Erfassungsliste vs. Parameterliste

Schauen wir uns also zwei Versionen desselben Codes an.

1) mit Fänger

int x = 4; 

cout << "With capture : Factorial of " << x << " = " << [x]() // <= Capture 
{ 
    int r = 1; 
    for (int i = x; i > 1; i--) r = r * i; 
    return r; 
}() << endl; 

2) Mit dem Parameter

int x = 4; 

cout << "With parameter: Factorial of " << x << " = " << [](int x) // <= Parameter 
{ 
    int r = 1; 
    for (int i = x; i > 1; i--) r = r * i; 
    return r; 
}(x) << endl; 

Der Ausgang ist:

With capture : Factorial of 4 = 24 
With parameter: Factorial of 4 = 24 

Da wir Parameter Lambdas in der Parameterliste übergeben können (genau wie bei jeder C++ Funktion), warum brauchen wir die Aufnahmeliste?

Kann mir jemand Fälle zeigen, in denen die Parameterliste nicht funktioniert und nur die Erfassungsliste funktioniert?

Antwort

11

Zum Beispiel mit stl Algorithmen:

std::vector<int> items; 
int factor; 
auto foundItem = std::find_if(items.begin(), items.end(), 
[&factor](int const& a) 
{ 
    return a * factor == 100; 
}); 

In diesem Fall Sie für jedes Element in dem Behälter in dem Lambda bezeichnet und Sie zurück, wenn die von einem erfassten Faktor multipliziert Wert ist 100. Der Code macht nicht viel Sinn, es ist nur ein Beispiel zu zeigen, wo Erfassung und Parameterlisten wichtig sind.

+1

können wir nicht beide 'a' und 'faktor' in der Parameterliste übergeben und das Capture leer lassen? –

+2

@ Xicod'Abrolha Wie? Du rufst das Lambda nicht auf, 'std :: find_if' macht es. Wie würdest du die Funktion anders nennen? – Angew

+2

kein Xico, können Sie nicht! in der find_if Code irgendwo haben Sie etwas, das Ihre Lambda (oder Funktion) wie folgt ruft: Handler (Wert); für jeden Wert im Bereich Beginn/Ende. –

3

Der Punkt ist, dass mit der Erfassung, können Sie einen Zustand (wie eine handgeschriebene Klasse mit operator()) in einem funktionsähnlichen Objekt. @dau_sama gibt eine gute Antwort. Hier ist ein weiteres Beispiel:

#include <iostream> 
using namespace std; 

int main() { 

    const auto addSome = [](double some){ 
    return [some](double val){ return some+val; } ; 
    }; 

    const auto addFive = addSome(5); 

    std::cout << addFive(2) << std::endl; 
}