在lambda函数中捕获和传递参数之间的区别

Arp*_*ana 23 c++ lambda function-pointers c++11

我理解lambda函数及其在c ++ 11中的用途.但我不理解"捕获值"和"传递参数"之间的区别.例如..

#include <iostream>
#include <functional>
using namespace std;

int add(int a,int b){
    return a+b;
}

int main(int argc, char** argv){

    function <int(int,int)> cppstyle;
    cppstyle = add;

    auto l = [] (function <int(int,int)> f,int a, int b) {return f(a,b);};

    cout << l(cppstyle,10,30) <<"\n";   
}
Run Code Online (Sandbox Code Playgroud)

上面代码的输出与下面的代码相同.

#include <iostream>
#include <functional>
using namespace std;

int add(int a,int b){
    return a+b;
}

int main(int argc, char** argv){

    function <int(int,int)> cppstyle;
    cppstyle = add;

    auto l = [cppstyle] (int a, int b) {return cppstyle(a,b);};

    cout << l(10,30) <<"\n";    
}
Run Code Online (Sandbox Code Playgroud)

"捕获一个值"类似于"将值作为参数传递"?或捕获有一些特殊意义?

101*_*010 20

通过类比可以看出所捕获的论证与传递论证之间的区别.考虑以下函数对象:

struct Capture {
  int &i;
  int const j;
public:
  Capture(int &_i, int &_j) : i(_i), j(_j) {}
  int operator()(int const a, int const b) {
    i *= j;
    return a * b;
  }
};
Run Code Online (Sandbox Code Playgroud)

在函数对象类中Capture有两个成员变量ij.还有重载operator(),它需要两个输入参数.现在考虑以下lambda:

int i, j;
[&i, j](int const a, int const b) {
  i *= j;
  return a * b;
};
Run Code Online (Sandbox Code Playgroud)

类的成员变量Capture都与拉姆达捕获类比(即,[&i, j]),而重载输入参数operator() ab分别与输入参数类比ab上面所示的拉姆达.

也就是说,如果将lambda视为函数对象,则其捕获是函数对象的状态(即其成员变量),而其输入参数将是重载的输入参数operator().


Nev*_*vin 11

在更高级别,您可以捕获现在知道的数据,并在需要拨打电话之前传入您没有的数据.

例如,假设您想为向量中的每个数字添加常量.你可以写它(警告:未经测试):

void Add(std::vector<int>& v, int i)
{
    std::for_each(std::begin(v), std::end(v), [i](int& j){ j += i; });
}
Run Code Online (Sandbox Code Playgroud)


小智 7

i 值的捕获是在定义 lambda 时设置的,而当 i 作为参数 (j) 传递时,它在循环中发生变化。

#include <iostream>
using namespace std;

int main(int argc,char **argv)   {
    auto i=5;
    auto f = [=](int j) {cout<<"capture i="<<i<<", passing i as j="<<j<< endl; };
    while (i<30) {
        i += 10;
        f(i);
    }
}
Run Code Online (Sandbox Code Playgroud)

--- 这将是输出:

lambda 捕获 i=5,将 i 作为参数传递 j=15

lambda 捕获 i=5,将 i 作为参数传递 j=25

lambda 捕获 i=5,将 i 作为参数传递 j=35

  • 感谢您揭露了这个陷阱。沿着 lambda 与函数对象的类比,这意味着捕获的“i = 5”是函数对象在创建期间的状态,当“i”在循环内更改时,函数对象的状态不会变化。改变了。 (2认同)