C++ 通用兰博达斯
这行代码(代码1)之间的区别是什么C++ 通用兰博达斯,c++,lambda,c++14,auto,generic-lambda,C++,Lambda,C++14,Auto,Generic Lambda,这行代码(代码1)之间的区别是什么 有时int变量“l”在调用之间共享,有时则不共享。有一个lambda参数的auto,它会创建多个lambda实例吗?我不能完全确定(代码1)与(代码2)有何不同,以及(代码2)与(代码3)有何不同。我期望(代码3)创建多个lambda实例,这样输出将是(Joe 1,Joe 2,1.5 1),但结果是(Joe 1,Joe 2,1.5 3)。在第一个示例中,静态变量的数量与lambda实例的数量一样多。其中可能有很多,因为您将参数指定为auto,这使lambda成
有时int变量“l”在调用之间共享,有时则不共享。有一个lambda参数的auto,它会创建多个lambda实例吗?我不能完全确定(代码1)与(代码2)有何不同,以及(代码2)与(代码3)有何不同。我期望(代码3)创建多个lambda实例,这样输出将是(Joe 1,Joe 2,1.5 1),但结果是(Joe 1,Joe 2,1.5 3)。在第一个示例中,静态变量的数量与lambda实例的数量一样多。其中可能有很多,因为您将参数指定为
auto
,这使lambda成为某种模板
第三个代码在每次创建lambda时按值捕获l
,并创建lambda的本地副本,因此不共享任何内容
让我们看一个例子。让我们使用内部定义的lambda创建一个函数f()
,并调用该函数两次:
void f() {
//auto l1 = ...
l1(1);
l1(2);
l1(3);
l1('a');
l1('b');
l1('c');
}
f();
std::cout << "---" << std::endl;
f();
对f()
的第二个调用允许您重用静态变量,但是对于两种不同的类型,有两个不同的变量
代码2:l
是唯一的静态变量,在所有lambda之间共享:
1 1
2 2
3 3
a 4
b 5
c 6
---
1 7
2 8
3 9
a 10
b 11
c 12
代码3:每个函数调用创建一个lambda,此lambda使用创建时捕获的变量l
的唯一实例:
1 1
2 2
3 3
a 4
b 5
c 6
---
1 1
2 2
3 3
a 4
b 5
c 6
如果再次运行此代码,您将看到再次创建l
,结果将重复
有一个lambda参数的auto,它会创建多个lambda实例吗
它不会创建多个lambda实例,但是lambda将有一个模板化的操作符()
,以及多个不同类型的实例
对于第一种情况,当使用const char*
调用两次时,将打印出相同的静态变量l
(在类型const char*
的操作符()的实例化中定义)。使用double
调用时,会打印静态变量l
(在类型double
的操作符()的实例化中定义),因此
Joe 1
Joo 2
1.5 1
Joe 1
Joo 2
1.5 3
Joe 1
Joo 2
1.5 3
对于第二种情况,它们都引用在lambda中定义的相同变量l
,然后您将得到
Joe 1
Joo 2
1.5 1
Joe 1
Joo 2
1.5 3
Joe 1
Joo 2
1.5 3
对于第三种情况,它们都引用lambda捕获的相同变量l
(甚至调用operator()
get的不同实例化),然后
Joe 1
Joo 2
1.5 1
Joe 1
Joo 2
1.5 3
Joe 1
Joo 2
1.5 3
对于此版本:
auto l1 = [](auto a) { static int l = 0; std::cout << a << " " << ++l << std::endl; };
static int l = 0;
auto l1 = [](auto a) { std::cout << a << " " << ++l << std::endl; };
对于此版本:
auto l1 = [](auto a) { static int l = 0; std::cout << a << " " << ++l << std::endl; };
static int l = 0;
auto l1 = [](auto a) { std::cout << a << " " << ++l << std::endl; };
第三个版本与第二个版本具有相同的效果,只是变量l
需要在函数局部范围内声明。代码1 vs代码2
static int l = 0;
auto l1 = [](auto a) { std::cout << a << " " << ++l << std::endl; };
代码1和2之间的区别只是实例化变量l
内部与外部的λ。不能保证代码2会看到l
,您肯定不应该更新l
,因为lambda没有捕获它
代码2对代码3
int l = 0;
auto l1 = [l](auto a) mutable { std::cout << a << " " << ++l << std::endl; };
这里的区别在于您已经捕获了l
[l]
,这意味着lambda可以在其范围内访问该变量。您还将lambda定义为mutable
,这意味着您可以更新已捕获的变量(l
)
代码3是正确的版本。由于您试图访问和更新变量l
,因此需要捕获它[l]
,并将lambda定义为可变的,以便更新它。lambda基本上只是声明函子的一种简单方法。此代码:
#include <iostream>
auto l1 = [](auto a) { static int l = 0; std::cout << a << " " << ++l << std::endl; };
static int m = 0;
auto l2 = [](auto a) { std::cout << a << " " << ++m << std::endl; };
int n = 0;
auto l3 = [n](auto a) mutable { std::cout << a << " " << ++n << std::endl; };
int main(){
l1("Joe");
l1("Joo");
l1(1.5);
std::cout << "\n";
l2("Joe");
l2("Joo");
l2(1.5);
std::cout << "\n";
l3("Joe");
l3("Joo");
l3(1.5);
}
#包括
自动l1=[](自动a){static int l=0;std::cout代码1
auto l1 = [](auto a) { static int l = 0; std::cout << a << " " << ++l << std::endl; };
l1("Joe");
l1("Joo");
l1(1.5);
autoL1=[](autoA){static int l=0;std::cout
class _tmp_lambda
private:
static int l = 0; /// <--
public:
{
_tmp_lambda() {}
void operator()(const char * a) const
{
std::cout << a << " " << ++l << std::endl;
}
void operator()(double a) const
{
std::cout << a << " " << ++l << std::endl;
}
};
int l = 0;
auto l1 = [l](auto a) mutable { std::cout << a << " " << ++l << std::endl; };
class _tmp_lambda
private:
int l = 0; /// <--
public:
{
_tmp_lambda(int _l):l(_l) {}
void operator()(const char * a) // Not a const
{
std::cout << a << " " << ++l << std::endl;
}
void operator()(double a) // Not a const
{
std::cout << a << " " << ++l << std::endl;
}
};