C++:lambda表达式中的捕获有什么作用?

3
捕获与将参数传递给lambda表达式有何不同?什么情况下我会使用捕获而不是只传递一些变量?
参考链接:http://en.cppreference.com/w/cpp/language/lambda#Lambda_capture 参考链接中只把它定义为“逗号分隔值的列表”,但没有解释它们的用途或者为什么要使用它们。
补充说明:这个问题不同于“什么是lambda表达式”因为我不是在问什么时候使用lambda表达式。我在问捕获的目的是什么。捕获是lambda表达式的一个组成部分,可以获取值,但在其他地方并没有很好地解释这些值所预期的目的,以及这与后跟捕获的传递值有何不同。

可能是什么是C++11中的lambda表达式?的重复问题。 - AndreyS Scherbakov
1
“我不是在问什么是lambda表达式或者何时使用它。” 捕获是lambda表达式的基本组成部分。 - Nicol Bolas
3
“Captures are a fundamental part of lambda expressions.”并不描述捕获的目的。 - dlo
2个回答

5

捕获是对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; };
}

请注意,此函数返回一个新的可调用对象,其 operator() 接受单个 int 并返回 int,内部使用一些值,该值是函数 f() 中本地变量的值,因此在控制退出函数后不再可访问。


3

您可能需要将lambda传递给调用它并带有特定数量参数(例如,std::find_if将单个参数传递给您的函数)。捕获变量使您能够有效地拥有更多的输入(如果您通过引用捕获,则为输出)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接