看了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是複製品了