我在玩C++ 11的功能特性。我覺得奇怪的一件事是,lambda函數的類型實際上不是函數<>類型。更重要的是,lambda似乎並不能很好地處理類型推入機制。爲什麼在C++ 11中的lambda函數沒有函數<>類型?
附加是一個小例子,我測試了翻轉函數的兩個參數來添加兩個整數。 (我使用的編譯器是MinGW下的gcc 4.6.2。)在此示例中,使用函數<>明確定義了addInt_f
的類型,而addInt_l
是類型爲auto
的類型推理的lambda。
當我編譯的代碼,該flip
函數可以接受的明確的類型定義addInt的版本,但不是拉姆達版本,給了一個錯誤說, testCppBind.cpp:15:27: error: no matching function for call to 'flip(<lambda(int, int)>&)'
接下來的幾行表明,拉姆達版本(以及「原始」版本)可以被接受,如果它被明確地轉換爲適當的功能<>類型。
所以我的問題是:
爲什麼一個lambda函數沒有在首位
function<>
類型?在這個小例子中,爲什麼addInt_l
不是function<int (int,int)>
而是類型?從函數式編程的角度來看,函數/函數對象和lambda之間有什麼區別?如果有一個根本原因,這兩個必須是不同的。我聽說拉姆達可以轉換爲
function<>
,但它們不同。這是C++ 11的一個設計問題/缺陷,是一個實現問題,還是在區分兩者的方式方面有利?似乎只有addInt_l
的類型簽名提供了有關函數的參數和返回類型的足夠信息。有沒有辦法寫lambda,以便上述顯式類型轉換可以避免?
在此先感謝。
//-- testCppBind.cpp --
#include <functional>
using namespace std;
using namespace std::placeholders;
template <typename T1,typename T2, typename T3>
function<T3 (T2, T1)> flip(function<T3 (T1, T2)> f) { return bind(f,_2,_1);}
function<int (int,int)> addInt_f = [](int a,int b) -> int { return a + b;};
auto addInt_l = [](int a,int b) -> int { return a + b;};
int addInt0(int a, int b) { return a+b;}
int main() {
auto ff = flip(addInt_f); //ok
auto ff1 = flip(addInt_l); //not ok
auto ff2 = flip((function<int (int,int)>)addInt_l); //ok
auto ff3 = flip((function<int (int,int)>)addInt0); //ok
return 0;
}
你不應該服用'std :: function'參數,主要是因爲它禁止類型推導(這是你的問題)。 – 2012-07-24 10:22:02
相關:[C++ 11不會在涉及std :: function或lambda函數時推導出類型](http://stackoverflow.com/q/9998402/487781) – hardmath 2012-07-24 10:32:41
將Lambdas轉換爲匿名函子(或函數,如果它們不要捕捉環境)。將它們轉換爲std :: function將引入語言和庫之間的強大耦合,因此將是一個非常糟糕的主意。 – MFH 2012-07-24 10:33:37