2013-02-21 38 views
4

我正在學習對lambda特別感興趣的C++ 11。使用lambda作爲參數:std :: function或template?

經過一些實踐,我認爲lambda閉包是一個無名的函數對象。

所以我寫了這段代碼。

template <class callable_object> 
void lambda_caller(callable_object lambda) 
{ 
    std::cout<< sizeof(lambda) << endl; 
    lambda(); 
} 

我知道,我可以用std::function而不是使用模板,但我不希望在強制類型轉換的開銷。

但我發現一個問題,讀了這個問題:Why can't I create a vector of lambda in C++11?

的回答者說,「每個拉姆達具有即使它們具有相同的簽名不同的類型 - 」。

編譯器爲不同的類創建不同的代碼。

所以我認爲我的編譯器會在我給lambda的另一個定義通過時創建lambda_caller的另一個版本。

有什麼辦法可以避免它,除了使用std::function? lambda關閉沒有任何泛型類型嗎?

+2

是不是'std :: function'專門爲此設計的?你可以爲lambda編寫自己的包裝器,它爲客戶端代碼提供相同的對象類型,並允許你透明地調用任何不同的lambda綁定到它。如果你寫了一個好的實現,你最終會得到std :: function(或類似的)。 – utnapistim 2013-02-21 09:59:37

+3

@utnapistim:'std :: function'用於*存儲*可調用。如果您只想採取任何可調用的方式,請使用模板 - 這也使內聯更容易。如果你想存儲它,仍然使用模板,並在內部轉換爲'std :: function'。 – Xeo 2013-02-21 10:00:51

+0

我不知道有關packaged_task。當我不想(或需要)將我的類或函數轉換爲仿函數/ lambda類型(回調,事件通知接收器,錯誤處理策略等)時,我使用'std :: function's作爲輸入參數。 – utnapistim 2013-02-21 10:06:44

回答

5

你無法避免它。 Lambda只是一個運算符()()重載的類,它會執行您的代碼。所以不同的代碼 - 不同的類。

0

std::function是lambda關閉的通用類型。問題是每個lambda可能捕獲不同的變量。所以它不能簡化爲一個函數指針和一些數據,因爲lambda可能捕獲了3個變量,或者它可能捕獲了4個。std::function將負責確保爲數據分配了足夠的內存,但它來了(數據可能是堆分配的)。

但是,如果您想存儲多個lambda表達式,並且知道編譯時有多少個lambda表達式,您可以將它們存儲在std::tuple中。它允許每個lambda的不同類型。不幸的是,C++仍然沒有提供迭代元組的方法,但是可以使用Boost.Fusion

+0

C++提供了一種方法 - 我只有109個字符能夠在此評論中發佈[完整示例](http://liveworkspace.org/code/Hpv3w$25)。 – Yakk 2013-02-25 20:28:10

+0

@Yakk這很酷。當然,我並不是說這是不可能的,只是標準的C++庫沒有提供方法。 – 2013-03-03 16:30:24

相關問題