[英]C++11 lambdas to Function Pointer
我開始使用C ++ 11 lambdas開發應用程序,並且需要將某些類型轉換為函數指針。 這在GCC 4.6.0中完美運行:
void (* test)() = []()
{
puts("Test!");
};
test();
我的問題是當我需要在lambda中使用函數或方法局部變量時:
const char * text = "test!";
void (* test)() = [&]()
{
puts(text);
};
test();
G ++ 4.6.0給出了強制轉換錯誤代碼:
main.cpp: In function 'void init(int)':
main.cpp:10:2: error: cannot convert 'main(int argc, char ** argv)::<lambda()>' to 'void (*)()' in initialization
如果使用auto ,它可以正常工作:
const char * text = "Test!";
auto test = [&]()
{
puts(text);
};
test();
我的問題是:如何用[&]為lambda創建一個類型? 在我的情況下,我不能使用STL std :: function (因為我的程序不使用C ++ RTTI和EXCEPTIONS運行時),並且它有一個簡單的函數實現來解決這個問題?
我不能使用STL std :: function(因為我的程序不使用C ++ RTTI和EXCEPTIONS運行時)
那么你可能需要編寫自己的等價於std::function
。
std::function
的類型擦除的通常實現不需要RTTI來實現其大多數功能; 它通過常規虛函數調用工作。 所以編寫自己的版本是可行的。
實際上, std::function
唯一需要 RTTI的東西是target_type
和target
函數,它們不是世界上最有用的函數。 您可以在不調用這些std::function
情況下使用std::function
,假設您正在使用的實現不需要RTTI用於其常規業務。
通常,當您禁用異常處理時,程序會在遇到throw
語句時關閉並出錯。 並且由於std::function
會發出的大多數異常都不是你能夠從中恢復的東西(調用空function
,內存耗盡等),你可以只使用std::function
原樣。
只有沒有捕獲的lambda才能轉換為函數指針。 這是lambdas的擴展,僅適用於這種特殊情況[*]。 通常,lambdas是函數對象,您無法將函數對象轉換為函數。
具有狀態(捕獲)的lambda的替代方法是使用std::function
而不是普通函數指針。
[*]:如果保持狀態的lambda可以轉換為函數指針,那么狀態會保持在哪里? (注意,這個特殊lambda可能有多個實例,每個實例都有自己需要單獨維護的狀態)
如前所述,只有捕獲任何內容的lambda才能轉換為函數指針。
如果你不想使用或寫一些類似std :: function的東西,那么另一種選擇是將你原本捕獲的東西作為參數傳遞。 您甚至可以創建一個結構來保存它們。
#include <iostream>
struct captures { int x; };
int (*func)(captures *c) = [](captures *c){ return c->x; };
int main() {
captures c = {10};
std::cout << func(&c) << '\n';
}
另一種方法是使用不需要捕獲的global / static / thread_local / constexpr變量。
你可以使用std::function
,它不需要任何“運行時”。 否則, 請查看草圖如何自己實現std::function
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.