簡體   English   中英

C ++ 11 lambdas到函數指針

[英]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_typetarget函數,它們不是世界上最有用的函數。 您可以在不調用這些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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM