I've recently learned,我可以這樣做:衰減的lambda指向哪個函數存儲?它是如何釋放的?
並理解,自由捕獲拉姆達衰變到一個函數指針,as confirmed by GCC:
bool (*)()
但存儲實際的函數對象在哪裏? 它是如何釋放的?爲什麼我可以存儲一個指向臨時lambda的指針?我理解常量引用延長對象生命期的語言的角落案例,所以我期望lambda衰減到某種類型,而不是原始指針。
I've recently learned,我可以這樣做:衰減的lambda指向哪個函數存儲?它是如何釋放的?
並理解,自由捕獲拉姆達衰變到一個函數指針,as confirmed by GCC:
bool (*)()
但存儲實際的函數對象在哪裏? 它是如何釋放的?爲什麼我可以存儲一個指向臨時lambda的指針?我理解常量引用延長對象生命期的語言的角落案例,所以我期望lambda衰減到某種類型,而不是原始指針。
lambda不是一個指針,但可以轉換爲指向函數的指針。
函數不會像C++中的值那樣「存儲」。實際上,它們存在於可執行文件的代碼段中,並由可執行文件/ dll加載程序加載到寫保護的執行位集頁面中。
無狀態lambda的代碼沒有什麼不同。轉換隻是返回一個指向函數的指針,其效果與lambda的主體相同,不多也不少。
請記住,這隻適用於無狀態lambda。沒有非靜態數據要存儲。現在
,該+
事情是有點一招,因爲當你申請一元operator+
一個對象,轉換嘗試,和一個uniqie類型(函數對象函數指針轉換)被發現。
我猜具體代碼可能會有所幫助。
struct fake_lambda {
static void action(){ std::cout<<"hello?\n"; }
void operator()()const{action();}
using ptr=void(*)();
operator ptr()const{return &fake_lambda::action;}
};
現在auto f=+fake_lambda{};
是一個指向打印"hello?\n"
功能。
這與auto f=+[](){std::cout<<"hello\n";};
基本相同,但更詳細。
靜態/未保存的部分會讓我有點困惑......如果代碼保存在一個單獨的區域,這是否意味着我可以安全地[返回一個衰減的指針到本地lambda](http://coliru.stacked-crooked .COM/A/fc9d87a68f5c4795)? – Kahler
...或者是您提到的受保護段本地和展開就像本地變量時函數返回? – Kahler
@kahler C++沒有概念或可能性,指向實際函數的函數指針不再有效。 (它可以是未初始化的,或者是空的,或者是被賦值的,但是一個有效的函數指針和它的拷貝不會變得無效)。現實中動態鏈接和DLL卸載可能會發生,但C++標準沒有描述動態鏈接加載或卸載。簡而言之,就是dll中的lambda,並且dll已經被卸載了?可能不會,或者你會問一個不同的問題。所以指針對於程序的生命週期是有效的。 – Yakk
如果您有興趣,可以參考[Clang的源代碼](https://github.com/llvm-mirror/clang/blob/master/lib/Sema/SemaLambda.cpp#L1147)。 – chris
當你編寫'bool foo(){return true;}',然後寫'auto a = &foo;''foo'如何釋放?答:不是。 – immibis
@immibis這是啓發 – Kahler