在 lambda 函数中捕获和传递参数之间的区别
Difference between capturing and passing an argument in lambda functions
我了解 lambda 函数及其在 C++ 11 中的用途。但我不了解 "Capturing the value" 和 "Passing an argument" 之间的区别。
例如..
#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";
}
上面代码的输出与下面的代码相同..
#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";
}
"capturing a value" 与 "passing a value as an argument" 相似吗?或者捕获有什么特殊意义?
捕获的参数和传递的参数之间的区别可以通过类比看出。考虑以下函数对象:
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;
}
};
函数对象classCapture
中有两个成员变量i
和j
。还有重载的 operator()
需要两个输入参数。现在考虑以下 lambda:
int i, j;
[&i, j](int const a, int const b) {
i *= j;
return a * b;
};
classCapture
的成员变量类似于lambda捕获(即[&i, j]
),而重载的operator()
[=19=的输入参数] 和 b
类似于上面显示的 lambda 的输入参数 a
和 b
。
也就是说,如果您将 lambda 视为函数对象,它捕获的是函数对象的状态(即它的成员变量),而它的输入参数将是重载的输入参数 operator()
.
在更高的层次上,您捕获您现在知道的数据,并在您需要进行调用之前传递您没有的数据。
例如,假设您想为向量中的每个数字添加一个常量。你可以这样写(注意:未经测试):
void Add(std::vector<int>& v, int i)
{
std::for_each(std::begin(v), std::end(v), [i](int& j){ j += i; });
}
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);
}
}
--- 这将是输出:
lambda capture i=5, passing i as argument j=15
lambda capture i=5, passing i as argument j=25
lambda capture i=5, passing i as argument j=35
我了解 lambda 函数及其在 C++ 11 中的用途。但我不了解 "Capturing the value" 和 "Passing an argument" 之间的区别。 例如..
#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";
}
上面代码的输出与下面的代码相同..
#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";
}
"capturing a value" 与 "passing a value as an argument" 相似吗?或者捕获有什么特殊意义?
捕获的参数和传递的参数之间的区别可以通过类比看出。考虑以下函数对象:
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;
}
};
函数对象classCapture
中有两个成员变量i
和j
。还有重载的 operator()
需要两个输入参数。现在考虑以下 lambda:
int i, j;
[&i, j](int const a, int const b) {
i *= j;
return a * b;
};
classCapture
的成员变量类似于lambda捕获(即[&i, j]
),而重载的operator()
[=19=的输入参数] 和 b
类似于上面显示的 lambda 的输入参数 a
和 b
。
也就是说,如果您将 lambda 视为函数对象,它捕获的是函数对象的状态(即它的成员变量),而它的输入参数将是重载的输入参数 operator()
.
在更高的层次上,您捕获您现在知道的数据,并在您需要进行调用之前传递您没有的数据。
例如,假设您想为向量中的每个数字添加一个常量。你可以这样写(注意:未经测试):
void Add(std::vector<int>& v, int i)
{
std::for_each(std::begin(v), std::end(v), [i](int& j){ j += i; });
}
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);
}
}
--- 这将是输出:
lambda capture i=5, passing i as argument j=15
lambda capture i=5, passing i as argument j=25
lambda capture i=5, passing i as argument j=35