0%

Capture this and *this in C++ Lambda

看了C++17的文章之後,還是搞不太清楚兩者的差異,於是自己寫程式驗證一下

Capture this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <memory>
struct Obj {
Obj(int value) : v(std::make_unique<int>(value)) {}
~Obj() { printf("Obj have been destroyed\n"); }
Obj(const Obj& o) {
printf("Copy constructor invoked\n");
v = std::make_unique<int>(*o.v);
}
Obj(Obj&& o) {
printf("Move constructor invoke\n");
v = std::move(o.v);
}
auto test() { return [this] { printf("%d\n", *v); }; }
std::unique_ptr<int> v;

};
int main()
{
auto test = Obj(123).test();
test();
}

很不意外的,Crash掉了
如果我們把呼叫改成Obj(123).test()(),Obj的Lifetime就跟執行時間一樣長了,可以正常執行

Capture *this

1
2
3
struct Obj {
auto test() { return [*this] { printf("%d\n", *v); }; }
};

跟上面一樣,只是修改了capture this的方式

1
2
3
4
Copy constructor invoked
Obj have been destroyed
123
Obj have been destroyed

由此可見他會呼叫Copy construtor,然後摧毀了原先的Obj,lambda中的this指的就是Copy的Obj

Simulate *this without C++17

要這麼做也不是不行

1
2
3
struct Obj {
auto test() { return [self = *this] { printf("%d\n", *self.v); }; }
};

C++17的程式碼比較乾淨,不過這個版本就很清楚知道這個this是複製品了