C++:lambda 表达式中捕获的目的是什么?

C++ : What are the purpose of captures in lambda expressions?

捕获与将参数传递到 lambda 表达式有何不同?什么时候使用捕获而不是只传递一些变量?

供参考:http://en.cppreference.com/w/cpp/language/lambda#Lambda_capture

该参考文献仅将其定义为 "list of comma separated values",但并未说明它们的用途或我使用它们的原因。

补充:这与 "what is a lambda expression" 不是同一个问题,因为我不是在问什么是 lambda 表达式或何时使用它。我在问 capture 的目的是什么。捕获是 lambda 表达式的一个组成部分,可以取值,但在互联网上的其他地方并没有很好地解释这些值的预期用途是什么,以及它与捕获后传递的值有何不同。

您可能希望将您的 lambda 传递给使用特定数量参数调用它的函数(例如,std::find_if 将单个参数传递给您的函数)。捕获变量允许您有效地拥有更多输入(或输出,如果您通过引用捕获)。

捕获是对 lambda 形式的自由变量的绑定。他们将 lambda 表达式转换为封闭形式(闭包),没有自由变量。考虑:

auto f1 = [](int a, int x, int y){ return a * x + y; };
int x = 40, y = 2;
auto f2 = [x, y](int a){ return a * x + y; };

尽管主体相同,但在第二种形式中,x 和 y 是自由变量(它们不受函数参数的约束),因此需要在形式实例化时绑定到现有对象(即捕获)。正如您首先建议的那样,在第一种形式中,它们是函数参数,因此在表单实例化时不需要绑定到现有对象。区别很明显:f1 是三个参数的函数,而 f2 只接受一个参数。

更重要的是,捕获保留了 lambda 本地上下文的一部分,它可以比上下文本身更有效。一个简单的例子:

auto f(int x) {
    return [x](int a){ return a + x; };
}

注意这个函数 returns 一个新的可调用对象,它的 operator() 接受一个 int 和 returns 一个 int,并且在内部使用一些值,一个变量的值是函数 f() 的局部变量,因此在控件退出函数后无法再访问。