c++的lambda捕获-02
单纯记录一点东西,代码都是cpp insight生成的
代码大概是
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <cstdio>
#include <iostream>
using namespace std;
struct test{
int id_ = 0;
auto get() {
auto func = [=]() {
cout << id_ << '\n';
};
return func;
}
};
int main()
{
test t;
auto res = t.get();
}
等价于
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <cstdio>
#include <iostream>
using namespace std;
struct test
{
int id_ = 0;
inline __lambda_9_16 get()
{
class __lambda_9_16
{
public:
inline /*constexpr */ void operator()() const
{
std::operator<<(std::cout.operator<<(__this->id_), '\n');
}
private:
test * __this;
public:
// inline /*constexpr */ __lambda_9_16(__lambda_9_16 &&) noexcept = default;
__lambda_9_16(test * _this)
: __this{_this}
{}
};
__lambda_9_16 func = __lambda_9_16{this} /* NRVO variable */;
return func;
}
// inline constexpr test() noexcept = default;
};
int main()
{
test t = test();
__lambda_9_16 res = t.get();
return 0;
}
这个是c++20以前的,=
还是会默认捕获this,20开始这个就编译不过了,会默认不捕获this。如果有同名变量在局部的话,实测会优先捕获局部的。
比如,局部放一个id_ = 1, 生成的代码类似
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
struct test
{
int id_ = 0;
inline __lambda_10_16 get()
{
int id_ = 1;
class __lambda_10_16
{
public:
inline /*constexpr */ void operator()() const
{
std::operator<<(std::cout.operator<<(id_), '\n');
}
private:
int id_;
public:
// inline /*constexpr */ __lambda_10_16(__lambda_10_16 &&) noexcept = default;
__lambda_10_16(int & _id_)
: id_{_id_}
{}
};
__lambda_10_16 func = __lambda_10_16{id_} /* NRVO variable */;
return func;
}
// inline constexpr test() noexcept = default;
};
另外msvc有一个bug
1
2
3
4
5
6
7
struct S {
static void Method();
void Method(int x);
void Test() {
auto f = [/*this*/] { S::Method(); };
}
};
这里一定要带一个this,不然会有warning,这个是msvc的一个bug,修复在vs2019直接带上
/Zc:lambda
/std:c++latest
虽然理论上他解析出来的应该类似是下面的,应该不需要this的才是
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
struct S
{
static void Method();
void Method(int x);
inline void Test()
{
class __lambda_10_14
{
public:
inline /*constexpr */ void operator()() const
{
Method();
}
using retType_10_14 = auto (*)() -> void;
inline constexpr operator retType_10_14 () const noexcept
{
return __invoke;
};
private:
static inline /*constexpr */ void __invoke()
{
__lambda_10_14{}.operator()();
}
};
__lambda_10_14 f = __lambda_10_14{};
}
};
This post is licensed under CC BY 4.0 by the author.