Lambda函数捕获变量vs返回值

Lambda function capture a variable vs return value?

本文关键字:vs 返回值 变量 函数 Lambda      更新时间:2023-10-16

我正在学习c++11的新函数lambda函数,我有点困惑。我读到

 []         Capture nothing (or, a scorched earth strategy?)
 [&]        Capture any referenced variable by reference
 [=]        Capture any referenced variable by making a copy
 [=, &foo]  Capture any referenced variable by making a copy, but capture variable foo by reference
 [bar]      Capture bar by making a copy; don't copy anything else
 [this]     Capture the this pointer of the enclosing class

我的问题是捕获变量到底意味着什么,返回值的区别是什么,如果你想捕获一个变量,你必须返回它对吗?

例如:

[] () { int a = 2; return a; } 

为什么不

int [] () { int a = 2; return a; }

您可以"捕获"属于封闭函数的变量。

void f() {
    int a=1;
    // This lambda is constructed with a copy of a, at value 1.
    auto l1 = [a] { return a; };
    // This lambda contains a reference to a, so its a is the same as f's.
    auto l2 = [&a] { return a; };
    a = 2;
    std::cout << l1() << "n"; // prints 1
    std::cout << l2() << "n"; // prints 2
}

如果需要,可以返回捕获的变量,也可以返回其他内容。返回值与捕获无关。

捕获列表用于将符号带入 lambda。返回值用于从 lambda返回

同样,lambdas使用尾随返回类型语法,如[] () -> int { int a=2; return a; }。不过通常最好还是隐式推导

lambda函数的一个关键特性是它可以记住声明它的作用域中的内容:

#include <iostream>
#include <vector>
#include <functional>
auto f(int i, int j) {
    int k = i * j;
    return [=](){ std::cout << k << "n"; };
}
int main() {
    std::vector<std::function<void(void)>> v;
    v.push_back(f(2,2));
    v.push_back(f(6, 7));
    for (auto& l: v) {
        l();
    }
}

请注意,当我们调用lambda时,我们不需要传递任何东西给它。

lambda本质上是围绕函子对象的语法糖,而捕获是向函子添加成员变量的过程:

[](char* p){ *p = toupper(*p); }
struct Lambda1 {
    int operator(char* p) const { *p = toupper(*p); }
};
int x = 42;
int y = 5;
[x, &y](int i){ return i * (x + y); }
struct Lambda2 {
    int x_;
    int& y_;
    Lambda2(int x, int& y) : x_(x), y_(y) {}
    int operator(int i) { return i*(x_ + y_); }
};

从lambda返回值是可选的,但是返回值是lambda的输出,而不是输入。